ScheduledThreadPoolExecutor executeNow(); - java

How can I tell ScheduledThreadPoolExecutor(let's call him sht) to execute his task when a button is pressed ?
For example if I have something like this :
sht.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
method1();
method2();
method3();
}
}, 0, 5, TimeUnit.MINUTES);
The methods that are inside sht will execute every 5 minutes but what I want to do is to run them "at now" . I can't just call the methods because some reasons.
I need something like this :
sht.executeNow();

The base execute() method of the Executor interface allows queuing tasks for immediate execution. You should hold a reference to the scheduled Runnable task and submit it for immediate execution on the click of the button.
In case you want to reset the scheduling after the button is clicked, you can do that by removing the previous Runnable task via the remove() method and rescheduling it. The execute() method would not be needed in that case, as you can achieve immediate execution by specifying an initial delay value of 0 in your scheduling method.
Considering your simple use-case, you might want to look at using a Timer instead of ScheduledThreadPoolExecutor, as it provides a much simpler API for what you are attempting. In fact, unless you really need to run these tasks in another Thread, you should use a Handler, which will manage the scheduling and execution of the tasks without needing to start new Threads.

Related

Should I use #Scheduled or sleep in rest controller?

I need to invoke some delayed action after calling my rest controller from frontend. For example after calling endpoint /controller with method Update. I want to get response status OK and in the controller call scheduler which will execute some update function on my entities in database after 15 minutes after call endpoint only once. I just want to simple change 2 boolean fields with delay. What should I use? #Schedule annotation or just sleep or maybe something else? I would be grateful for all advices.
Best regards!
#Scheduled is meant for periodic execution of a certain method. For what you want you should use the ScheduledExecutor class. See the documentation for more details https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html
It has two methods, the scheduleWithFixedDelay method is the one you want to use.
EDIT: Heres an example
final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
executorService.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
//Do you database save here
}
}, 0, 15, TimeUnit.MINUTES);
EDIT 2:
Maybe its simpler to just use the schedule() method instead, since you are only doing one update. The example above is for when you have multiple actions that must each be done successively with a fixed delay of 15 minuten between executions. For only one execution you could use:
executorService.schedule(() -> database.save(), 15, TimeUnit.MINUTES);
executorService.shutdown();
the code () -> database.save() is called a lambda expression.
calling shutdown after the schedule call is important or else you might get memory leaks. The shutdown() method will wait for the thread in the executorService queue to be executed after which it will destroy the thread used.

Terminate Runnable

I have a task executor which takes runnable as a task. I am starting a timer before calling runnable.run() method and stopping it when the runnable finished. I want to terminate the execution of run() method from the executor itself if the timer exceeds the time limit. I do not know what user will implement in run().
TaskExecutor.add(new Runnable () {
#Override
public void run() {
System.out.println("This is test job");
}}
);
This is how the user adds a new task. Every task runs in the same thread.
Edit
This task executor will act as a service to users. And because creating threads are expensive operation and requires native OS calls, I am trying to avoid them. Otherwise I would call Thread.interrupt() at some point. But I just want to know if there is a way to terminate the run() method from a parent object. Terminate means to stop something abruptly. As how we terminate processes in OS task manager.
How tasks are executed
while (jobQueue.isEmpty()) {
for (Job job : jobQueue) {
long startTime = System.currentTimeMillis();
job.run();
//There is a separate thread which checks
//for timeout flags by comparing the startTime
//with the current time. But all tasks are
//executed in the same thread sequentially. I
//only want to terminate single jobs that are
//timed out.
}
}
you can check condition for your timer,if timer exceeds you can interrupt your thread like-
Thread.currentThread().interrupt();
It will stop your current Thread.
I just want to know if there is a way to terminate the run() method from a parent object.
You can't really terminate a method, and you can't really do anything from an object.
It's often convenient to say "this object does X," or "this method does Y," but objects and methods don't really do anything. When you're talking about multi-threaded code, it's important to realize that everything your program does is done by threads. Methods are just the instructions that tell threads what to do, and objects are what the threads do it to.
You can interrupt a thread, which is only a good idea if the thread is designed to gracefully handle the interrupt; and you can terminate a thread, which basically is never a good idea.
Threads should always cooperate with one another. You need to provide a means by which your program can politely ask the client-provided callback to abort its work and return early. If the client code does not respect your request (i.e., if the client code does not cooperate), that's the client programmer's fault for not obeying your guidelines.
The simplest way to do it would be to simply expose some static boolean method that the client can periodically check to see whether it's time to abort.

ScheduledExecutorService scheduleWithFixedDelay for Callable

I am trying to execute a periodic action using Java Concurrency package and I am using the following code:
ScheduledExecutorService daemon = Executors.newScheduledThreadPool(1);
daemon.scheduleWithFixedDelay(new AddressThread(ParentMap.getSingletonInstance(), dictionary, test),10, 10, TimeUnit.SECONDS);
where AddressThread is a Runnable type that is passed. The code executes run() every 10 seconds and it is working as I expect. However, I need to return a value and run() does not let me do that. Is there a similar method like scheduleWithFixedDelay where I can pass a Callable interface rather than a Runnable and return something back? If not, how can I do equivalent stuff like above if I want to return a value?
The problem is where do you want to process the result. If your task is executed once you will get the result of the task from the returned ScheduledFuture (see here: here)
When you have several calls noone is able to distinguish when the return value is available.
You could either implement a Listener and call it at the end of your task, our you have a seperate thread, that waits until the result is available, processes it and then schedules the next execution.

Java's FutureTask composability

I try to work with Java's FutureTask, Future, Runnable, Callable and ExecutorService types.
What is the best practice to compose those building blocks?
Given that I have multiple FutureTasks and and I want to execute them in sequence.
Ofcourse I could make another FutureTask which is submitting / waiting for result for each subtask in sequence, but I want to avoid blocking calls.
Another option would be to let those subtasks invoke a callback when they complete, and schedule the next task in the callback. But going that route, how to I create a proper outer FutureTask object which also handles exceptions in the subtask without producing that much of a boilerplate?
Do I miss something here?
Very important thing, though usually not described in tutorials:
Runnables to be executed on an ExecutorService should not block. This is because each blocking switches off a working thread, and if ExecutorService has limited number of working threads, there is a risk to fall into deadlock (thread starvation), and if ExecutorService has unlimited number of working threads, then there is a risk to run out of memory. Blocking operations in the tasks simply destroy all advantages of ExecutorService, so use blocking operations on usual threads only.
FutureTask.get() is blocking operation, so can be used on ordinary threads and not from an ExecutorService task. That is, it cannot serve as a building block, but only to deliver result of execution to the master thread.
Right approach to build execution from tasks is to start next task when all input data for the next task is ready, so that the task do not have to block waiting for input data. So you need a kind of a gate which stores intermediate results and starts new task when all arguments have arrived. Thus tasks do not bother explicitly to start other tasks. So a gate, which consists of input sockets for arguments and a Runnable to compute them, can be considered as a right building block for computations on ExcutorServices.
This approach is called dataflow or workflow (if gates cannot be created dynamically).
Actor frameworks like Akka use this approach but are limited in the fact that an actor is a gate with single input socket.
I have written a true dataflow library published at https://github.com/rfqu/df4j.
I tried to do something similar with a ScheduledFuture, trying to cause a delay before things were displayed to the user. This is what I come up with, simply use the same ScheduledFuture for all your 'delays'. The code was:
public static final ScheduledExecutorService scheduler = Executors
.newScheduledThreadPool(1);
public ScheduledFuture delay = null;
delay = scheduler.schedule(new Runnable() {
#Override
public void run() {
//do something
}
}, 1000, TimeUnit.MILLISECONDS);
delay = scheduler.schedule(new Runnable() {
#Override
public void run() {
//do something else
}
}, 2000, TimeUnit.MILLISECONDS);
Hope this helps
Andy
The usual approach is to:
Decide about ExecutorService (which type, how many threads).
Decide about the task queue (for how long it could be non-blocking).
If you have some external code that waits for the task result:
* Submit tasks as Callables (this is non blocking as long as you do not run out of the queue).
* Call get on the Future.
If you want some actions to be taken automatically after the task is finished:
You can submit as Callables or Runnables.
Just add that you need to do at the end as the last code inside the task. Use
Activity.runOnUIThread these final actions need to modify GUI.
Normally, you should not actively check when you can submit one more task or schedule callback in order just to submit them. The thread queue (blocking, if preferred) will handle this for you.

Java Timer Reusage

I'm currently trying to get a small brick-breaker game I made to effectively use some form of power-ups or bonuses. I have have it mostly implemented right now. However I have a problem. I use java.util.Timer to determine how long the power-up lasts. Most likely, that power-up is going to be chosen (by a random number generator) more than once. However, a Java Timer can only be used once, and after it's cancel() method is called, it's done. Right now, I set up the game to mark a power-up as used and to never use it again. Is there a way to get around this? Here's the method that is called when the LongPaddle power-up is chosen:
public void longPaddleTime(int seconds) { //longPaddle Timer Method - gets called when the longPaddle bonus is enabled; shuts off longPaddle after a set amount of time
timerLP.schedule(new TaskLP(), seconds*1000);
}
class TaskLP extends TimerTask { //The task to be run after the timer in longPaddleTime runs out
public void run() {
longPaddle=false; //Disable LongPaddle
bonusActive=false;
LPused=true; //Mark as used
timerLP.cancel(); //Terminate the timer thread
timerLP.purge();
}
}
You don't need to cancel() your timer - Timer.schedule(TimerTask, long delay) will only run the specified task once. You only need to cancel() a timer if you want to terminate everything it's doing.
For your case (scheduling a task once), there's no cleanup required in the Timer class. If you had a repeating task and you wanted to stop just that one task, you could call TimerTask.cancel() to prevent it from reoccuring, while still allowing the Timer to be reused for other purposes.
You don't have to cancel the timer in your TaskLP.
Create a Timer object that lives in Application scope and just schedule new TimerTasks as need arises.
BTW, although not officially deprecated, Timer functionality has been superseeded by ScheduledExecutorService. I suggest, if you start from scratch to use this framework.
Executors utility class has a few methods that simplify the construction of the ScheduledExecutorService.

Categories

Resources