interfere with ScheduledThreadPoolExecutor's schedule - java

I used ScheduledThreadPoolExecutor.scheduledAtFixedRate to schedule some task to run every dt interval.
But sometimes, I do want to force the task to be executed immediately. After the task has executed, I want the schedule to go back to normal. (ie., some dt amount of time after this 'forced' execution, the task should be executed again).
Is it possible to do that with ScheduledThreadPoolExecutor? Could you show me how? Some simple example would be great!
I suppose one could do this by simply shutting down the schedule, executing the task manually, and calling scheduleAtFixedRate again, but I'm wondering if that's good practice.
Thanks

That's a good question. Maybe you could call cancel() on the ScheduledFuture<T> that you received from calling scheduledAtFixedRate(), submit the task manually using submit(), and then reschedule your fixed rate task again when that Future comes back? You would have to check that the task isn't already running I suppose.
Some pseudocode...
ScheduledFuture<Thingy> sf = executor.scheduleAtFixedRate(myTask, etc...);
sf.cancel();
final Future<Thingy> f = executor.submit(myTask);
f.get();
sf = executor.scheduleAtFixedRate(myTask, etc...);
I've never done it, it's an interesting question.

For a one shot execution use
ScheduledFuture<Thingy> sf = executor.schedule(myTask, 0, SECONDS);
This will execute myTask once and immediate but won't stop executing the tasks scheduled before with an interval. Is that really a problem?

Related

Which one of these two methods should I use to stop correctly a scheduled thread?

I created a simple task, to run every two minutes, that I want to stop once a boolean becomes true.
ScheduledExecutorService scheduledxecutor = Executors.newScheduledThreadPool(1);
ScheduledFuture<?> scheduledFuture = scheduledExecutor.scheduleAtFixedRate(drawRunnable , 0, 2, TimeUnit.MINUTES);
I've been lurking around stackoverflow and I basically found that I need to use either scheduledFuture.cancel(false) or scheduledExecutor.shutdown().
Which one should I use?
scheduledExecutor.shutdown() is the better choice b'coz it gracefully starts the shutdown of all the tasks submitted whereas scheduledFuture.cancel(false) only deals with that particular task only.
ExecutorService.shutdown() Java Doc
Future.cancel(boolean) Java
Doc
If the executor service has no tasks, it remains still alive and is ready to be used again. Some resources remain blocked. If you use the executor for this single task only, then better is to use scheduledExecutor.shutdown(). It will wait until the current tasks are completed and will not start new ones. So it is safe to call it even if the task is running at the moment.
But if you add some more tasks to this executor service, it is better to cancel a particular task only. Then you will be sure that you don't cancel any other tasks.

schedule on task at a time - java

I have a task that is scheduled periodically. Sometime it can take longer than expected.
I am trying to find a way to make sure that scheduling will be canceled in case the task is already running. All mechanisms I check will make the task wait and run it after the first finish
locking ofcourse will do the job but I'm looking of something more high level
Any Idea
You can use ScheduledExecutorService. scheduleAtFixedRate is probably what you want as it will wait for your tasks to finish, iff one takes longer than the rate you specify:
If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.
Example:
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(() -> {
// Body will be executed every second unless the previous task hasn't finished.
}, 0L, 1L, TimeUnit.SECONDS);
There is something called scheduleAtFixedRate and scheduleAtFixedDelay.
scheduleAtFixedRate will start another process at defined time, so if previous process is not completed, two processes will be running and it might cause race condition of running same thing twice.
scheduleAtFixedDelay will start after fixed time once a task is completed.
scheduleAtFixedRate vs scheduleWithFixedDelay
In Spring you can do this by using annotation:-
#Scheduled(fixedDelay =30000)
http://howtodoinjava.com/spring/spring-core/4-ways-to-schedule-tasks-in-spring-3-scheduled-example/
do you know Apache Camel framework?
It has a module called quartz2 and has a much possibility to scheduling any task.
try read this page:
http://camel.apache.org/quartz2.html

How to remove/postDelayed runnables in Java?

Upon an event, I'd like to run a task/runnable but delay it's execution in 2 seconds.
During these 2 seconds, if the same event occurs, I'd like to remove the previous task and re-post it to run - again delayed by 2 seconds.
An example scenario would be background compilation. When a file is saved, I'm waiting 2 seconds and start compiling the class and other, depending classes. I don't want to do it all the time - especially if there are editors that save files automatically, like IntelliJ IDEA.
So, how can I remove/postDelayed runnables in Java, like Android's Handler (remove / postDelayed)?
you can use the Executors.newScheduledThreadPool in order to schedule the task,
and you can follow this post's answer :
BlockingQueue<Runnable> queue = threadPool.getQueue();
in order to get the queued runnables.
To delay any task and "restart" the delay, you can use Swing timer and if it is running, use its method restart.
I suppose you could use the ScheduledExecutor to accomplish this, by adding a mechanism to replace queued tasks with re-queued ones. You could look into the source code of ScheduledThreadPoolExecutor to give an idea, perhaps overriding the implementation of ScheduledFuture<?> schedule( Runnable command, long delay, TimeUnit unit ) and figuring out to avoid the scheduling, only running the tasks once.
Cheers,

check if the timer has any pending tasks?

I use the Java's Timer to schedule a task to run after some interval of time.
myTimer.schedule(myTask, delayTime);
At any point in time, is it possible to check if there is any task scheduled to be run (but has not run yet)? If so, how would I do that?
If not, what is the alternative(s) to Timer do I have?
You can (and should) use ScheduledExecutorService instead of Timer.
It handles thread crashes in a robust manner and has more flexible API
You can just add a boolean field to myTask's class, which will be set true at first execute.
Keep it simple.

Schedule a single-threaded repeating runnable in java, but skip the current run if previous run is not finished

Sometimes the duration of a repeated task is longer than its period (In my case, this can happen for hours at a time). Think of a repeated task that takes 7 minutes to run and is scheduled to run every 10 minutes, but sometimes takes 15 minutes for each run for a few hours in a row.
The Timer and ScheduledThreadPoolExecutor classes both have a scheduleAtFixedRate method that is usually used for this type of functionality. However, both have the characteristic that they 'try to catch up when they fall behind'. In other words, if a Timer falls behind by a few executions, it builds up a queue of work that will be worked on continuously until it catches back up to the number of runs that would have happened if none of the tasks had taken longer than the specified period. I want to avoid this behavior by skipping the current execution if the previous run is not complete.
I have one solution that involves messing around with the afterExecution method of a pooled executor, recalculating a delay, and rescheduling the runnable with the new delay, but was wondering if there's a simpler way, or if this functionality already exists in a common library somewhere. I know about scheduling with a fixed delay rather than a fixed period, but this will not work for me since it's important to try to execute the tasks at their fixed times. Are there any simpler options than my afterExecution solution?
I think what you want is for the long-running task itself to not run in the ScheduledExecutorService itself, but in a background thread. Then the fixed-rate task will always complete quickly, since it is only used for checking whether to start the actual task in the background (or not, if it's still running from last time).
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
final Runnable actualTask = null;
executorService.scheduleAtFixedRate(new Runnable() {
private final ExecutorService executor = Executors.newSingleThreadExecutor();
private Future<?> lastExecution;
#Override
public void run() {
if (lastExecution != null && !lastExecution.isDone()) {
return;
}
lastExecution = executor.submit(actualTask);
}
}, 10, 10, TimeUnit.MINUTES);
You could use scheduleWithFixedDelay method instead. It's similar but this one does not have a queue for missed runs and instead starts counting again only when the current Runnable was terminated.
The documentation states the reexecution of the Runnable will be scheduled based on the delay parameter:
The delay between the termination of one execution and the commencement of the next.
Make a third class, say called Coordinator. Coordinator has a synchronized startRunning() method which sets isRunning to true and returns true if another thread was not running already. There should also be a synchronized stopRunning method which sets isRunning to false. It returns true if a runnable is already running. You make a single instance of this class and pass a reference to all of the runnables you construct. In the runnable's run method you first call startRunning and check the return to verify that another one isn't running already. Make sure to put the code in run() in a try-finally and call stopRunning from within the finally block.

Categories