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
Related
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.
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,
I am quite new to using Java SchedulerThreadPoolExecutor. I would like to ask if there is a way to implement a scheduler that matches the scenario:
At time t, a scheduler will take in all the tasks that are not processed and processed them.
At time t+1, there are new tasks coming but the scheduler is unable to take them since all the tasks at time t have not processed finished. Even if some of the task at time t has finished processing, the scheduler is unable to take in new task from time t+1 until all the tasks have completely processed. If that is the case, the scheduler will block the task at time t+1. Till all the task t+1 have fully processed, then the scheduler will take in new tasks at t+1.
It seems that you want to define task processing periods, where no task will cross a period boundary. Two questions/hints:
Why do you need to use SchedulerThreadPoolExecutor? Unless you intend to use its timer-like capabilities, which would probably conflict with your task period requirement anyway, a simple ThreadPoolExecutor should be enough.
Have you considered restructuring your code to use invokeAll()?
I have a task that needs to be executed on a schedule. (It basically polls a database looking for a change and then executes code depending on the result). The problem is that I need the polled task to happen even when it is already executing.
So far I have tried using a Timer/TimerTask combo with the scheduleAtFixedRate() method and the ScheduledThreadPoolExecutor/Thread combo with the scheduleAtFixedRate() method.
Both wait for the current scheduled task to complete before running the next. I need to be able to schedule a task to run every 5 seconds and have it run even if the last execution of the task has not yet completed.
Any ideas?
How about using one Timer as the "kick-off" timer, but then a separate thread pool for execution: when the timer ticks, you submit the task to the thread pool for immediate execution. (You may want to tweak the thread pool to have some maximum number of tasks running simultaneously.)
I am having this problem, I have
private ScheduledExecutorService executor =
Executors.newSingleThreadScheduledExecutor();
and task which is created every 50 millliseconds:
executor.scheduleAtFixedRate(myTask, 0, 50, TimeUnit.MILLISECONDS);
myTask sometimes take a while to complete (like 2-3 seconds or so), but newSingleThreadScheduledExecutor guarantees that next scheduled myTask will wait until the current one completes.
However, I get this error from time to time:
execute: java.util.concurrent.RejectedExecutionException
What should I do? Thanks
Consider what the executor is doing. It is running a single task every 50 milliseconds, as per your instructions. Assuming this task takes less than 50 milliseconds to run, then everything is fine. However, every so often it takes 2-3 seconds to run. When this happens, the executor still tries to execute every 50 milliseconds, but because it only has a single thread, it can't, and rejects those executions that are being triggered while your long-running task is still going. This causes the exception you see.
You have two choices to fix this (assuming you want to stick with a single thread):
Use scheduleWithFixedDelay rather than scheduleAtFixedRate. If you read the javadoc carefully, you'll see that scheduleWithFixedDelay will wait 50 milliseconds between the finishing of one task and the start of the next, so it will never "overlap", even if one of them takes a long time. In contrast, scheduleAtFixedRate will try to execute every 50 milliseconds, regardless of how long each one takes.
Change the way that the executor handles failures to execute. The default is to log an exception, but you can tell it to ignore it, for example. Take a look at the subclasses of of java.util.concurrent.RejectedExecutionHandler, for example DiscardPolicy, which just silently drops the task that can't be run. You can use these by directly constructing ScheduledThreadPoolExecutor and passing in the handler to the constructor, rather than using the Executors factory class.
I suspect option (1) is what you want.
This exception will be thrown when either:
You have shutdown the Executor
The Executor's bounds for its work queue or maximum threads have been exceeded.
I assume the latter is happening. When you execute your task and it takes a long time then subsequent scheduled tasks can not be run because there are not enough threads available in the pool.
Either:
Use use a larger pool size or use cachedThreadPool
Change the rejection policy to for example use ThreadPoolExecutor.CallerRunsPolicy
Create a separate Executor for running the long run tasks and run these from your scheduled task. In actual fact you can do this using the same Executor instance providing that you increase the pool size.
See also ThreadPoolExecutor javadoc
With Java 7 both of them will wait till the first execution is ready and then start the next!
check here:
http://download.java.net/jdk7/archive/b123/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html
or here:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html