Suspend TimerTask until the next execution - java

I am using a TimerTask to run some periodic tasks, the task being processing a set of files. I have a requirement where if the number of files to be processed exceeds a pre-determined limit, the thread suspends execution and waits till the next cycle to start processing the files again. Is there a way to suspend the TimerTask until the next execution period or do I have to extend the TimerTask class to achieve this functionality? I saw there is a TimerTask.cancel method, but this will cancel all further executions of this thread. I don't want this to happen. I just want the thread to be suspended until the next execution period. I don't have the luxury of moving to any of the other concurrent classes in Java as our framework uses TimerTask, and I have to stick with it.
Any suggestions, pointers or tips are greatly appreciated.
thanks,
Asha

One approach would be to put the tasks on a BlockingQueue and let the TimerTask remove() and process entries until the queue is empty or the pre-determined limit has been reached. Any remaining entries will be in the queue waiting for the next scheduled execution.

Related

Skip to next task in a single threaded ExecutorSerivce?

I am considering an implementation of an ExecutorService to run a series of tasks. I plan to use the internal queue to have a few tasks waiting for their turn to run. Is there some way to interrupt the task (the Runnable) that is currently running in an ExecutorService thread, and keep the thread alive to run the next task? Or is only possible to call .shutdown() and then create a new ExecutorService?
I have found this and wanted to know if there are any other solutions.
Instead of interfering with the threads you may want to have a Task class (that extends or wraps the Runnable) which implements an interrupt mechanism (e.g. a boolean flag).
When you execute your task you need to check this flag periodically and if it is set, the task should stop what it is doing. You might want to return a specific result at this point, that tells your code that the task was cancelled succesfully.
If a user now decides that he no longer requires the results from this task,
you will have to set this flag. However the task might have already completed at this point of time so you still need to deal with the cases where the result already exists but the user does no longer care about it.
An interrupt on a thread level does not guarantee that the thread stops working. This will only work if the thread is in a state where it can receive an interrupt.
Also you should not interfere with the Threads of the ExecutorSerivce directly, as you might unintentionally stop a different task or stop the ExecutorSerivce from working properly.
Why would you want to kill that task and continue with the next one? If it is a question of times you can define that the threads that are taking longer than you declared in the method that executes them are automatically canceled. E.g:
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.invokeAll(Arrays.asList(new Task()), 60, TimeUnit.SECONDS); // Timeout of 60 seconds.
executor.shutdown();
If any of the threads takes longer than 60 seconds it will throw a cancellation.Exception() that you must catch

Java: Controlling hardware tasks with pausable ThreadPoolExecutor

I want to implement a single-producer - multi-consumer logic where each consumer processing time depends on a hardware response.
**EDIT
I have a Set of objects (devices). Each object (device) corresponds to a hardware real unit I want to simulate in software.
My main class distributes a list of tasks to each device. Each task takes a certain time to complete - which I want to have control, in order to simulate the hardware operation. Each device object has its own SingleThreadExecutorService service executor to manage its own queued tasks. A Sleep on a task of a specific device object should not interfere on main, or other devices object's performance.
So far things are working but I am not sure how to get a future from the tasks without blocking the main thread with a while(!future.isDone()). When I do it, two problems occur:
task 1 is submitted to device[ 1 ].executor. Tasks 1 sleeps to simulate hardware operation time.
task 2 should be submitted to device[ 2 ].executor as soon as task 1 is submitted, but it won't, because main thread is hold while waiting for task 1 to return a Future. This issue accumulates delay on the simulation since every task added causes the next device to have to wait for the previous to complete, instead of running simultaneously.
Orange line indicates a command to force device to wait for 1000 milliseconds.
When Future returns, it then submits a new task to device 2, but it is already 1 second late, seen in blue line. And so on, green line shows the delay increment.
If I don't use Future to get when tasks were finished, the simulation seems to run correctly. I couldn't find a way to use future.isDone() without having to create a new thread just to check it. Also, I would really be glad if someone could advice me how to proceed in this scenario.
If your goal is to implement something where each consumer task is talking to a hardware device during the processing of its task, then the run method of the task should simply talk to the device and block until it receives the response from the device. (How you do that will depend on the device and its API ...)
If your goal is to do the above with a simulated device (i.e. for testing purposes) then have the task call Thread.sleep(...) to simulate the time that the device would take to respond.
Based on your problem description (as I understand it), the PausableSchedulerThreadPoolExecutor class that you have found won't help. What that class does is to pause the threads themselves. All of them.
UPDATE
task 2 should be submitted to device[ 2 ].executor as soon as task 1 is submitted, but it won't, because main thread is hold while waiting for task 1 to return a Future.
That is not correct. The Future object is returned immediately ... when the task is submitted.
You mistake (probably) is that the main thread is calling get on the Future. That will block. But the point is that is your main thread actually needs to call get on the Future before submitting the next task then it is essentially single-threaded.
Real solution: figure out how to break that dependency that makes your application single threaded. (But beware: if you pass the Future as a parameter to a task, then the corresponding worker thread may block. Unless you have enough threads in the thread pool you could end up with starvation and reduced concurrency.)

How to relaunch a TimerTask

I have written a task to send a certain TCP message through a socket. I have a file with a bunch of messages and some timestamps, so I programmed the task as a TimerTask, and I scheduled it with a Timer with the first message timestamp.
When it finishes, the task run method is over, but its associated thread remains, it's not cancelled. If I try to reschedule the task with a new Time, I'm getting an exception telling me that I cannot reschedulle a schedulled or cancelled task.
I also tried cancellig it before rescheduling, but obviously, as the exception told, it remains the same problem.
I can't schedule the task with a constant perior to let it repeat itself, because each message has a time and it is not constant.
How can I reschedule the TimerTask? And by the way, is there any way of waiting for the task to end, just as in socket communications when it blocks with ready method until a message arrives?
A TimerTask is not designed to be rescheduled and it is the Timer that manages the (single) thread.
Use one Timer and many new TimerTasks:
Corresponding to each Timer object is a single background thread that is used to execute all of the timer's tasks, sequentially ..
After the last live reference to a Timer object goes away and all outstanding tasks have completed execution, the timer's task execution thread [should] terminates gracefully (and becomes subject to garbage collection).
[From each of the schedule methods:]
Throws IllegalStateException if [the TimerTask] was already scheduled or cancelled, timer was cancelled, or timer thread terminated.
If there are indeed many threads spawned by a single Timer, then that would be a bug which is unlikely: make sure there really is only one Timer object being used.
The last question, of how to compose individual events into a workflow, should be a separate post.

Java Concurrent Execution of Thread Task

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.)

handling sleep in java scheduled executor service

I have a sort of complex problem like below.
- we have a real time system with large number threads requirement. In order to optimize the performance, we are thinking of following design.
create a thread pool executor with max number of threads
each thread is used to create scheduled executor service.
now the tasks are being assigned to these executor services evenly based on load
BUT the biggest problem is, if one of the task in the queue contains a sleep (for few secs), it blocks the corresponding Schedule executor service thread for that duration and subsequently all the following tasks in that queue.
In this regard, please suggest me how to suspend the execution of the task with sleep OR overriding the sleep somehow and rejoin/schedule the task again to the queue.
Thanks in advance
Seshu
Assuming I understand your question, your Schedule Executor service threads have a deadline requirement, but the actual workers can sleep for an unknown length of time, possibly throwing off the timing of the Schedule Executors. From your description I'm guessing what you want is for a task that needs to sleep to actually stop, save progress information and then requeue itself for the remainder of the work to be rescheduled at some future time. You'd have to build this into your application architecture.
Alternatively, you could have the scheduler threads launch the worker tasks in their own separate threads, letting them sleep as necessary, with one scheduler thread collecting all the worker terminations.
To get a better answer you're going to have to provide more information about what you're trying to accomplish.
Tasks which sleep are inherently unfriendly for running in any kind of bounded thread pool. The sleep is explicitly telling the thread that it must do nothing for a period of time.
If possible, split the task into 2 (or more parts), eliminating the sleep completely. Get the first half-task to schedule the second task with an appropriate delay.
Failing that, you could consider increasing the size of your thread pool somewhat - either setting a much larger cap to its size, or possibly even eliminating the cap altogether (not recommended for a server than might end up with many clients).
Alternatively, move the tasks with sleep statements in them into their own Scheduled executor. Then, they'll delay each other, but better-behaved tasks, with no wait statements in them, will get preferential treatment.

Categories