I'm using java.util.concurrent.ExecutorService with fixed thread pool to execute list of tasks. My list of tasks will typically be around 80 - 150 and I've limited the number of threads running at any time to 10 as shown below:
ExecutorService threadPoolService = Executors.newFixedThreadPool(10);
for ( Runnable task : myTasks )
{
threadPoolService.submit(task);
}
My use case demands that even the completed task should be re-submitted again to the ExecutorService but it should be executed/taken again only when all the already submitted tasks are serviced/completed. That is basically, the tasks submitted should be executed on a rotation-basis. Hence, there will not be either threadPoolService.shutdown()
or threadPoolService.shutdownNow()
call in this case.
My question is, how do I implement ExecutorService servicing rotation-basis tasks?
The answer is more related to the implementation of the work queue used for the instance of
ExecutorService
. So, I'd suggest:First choose an implementation of
java.util.concurrent.BlockingQueue
(an example) that provides a circular queue functionality. NOTE, the reasonBlockingQueue
has been chosen is that to wait until the next task is provided to queue; so, in case of circular + blocking queue, you should be careful how to provide the same behavior and functionality.Instead of using
Executors.new...
to create a newThreadPoolExecutor
use a direct constructor such asThis way, unless you command the executor to
shutdown
, it will try to fetch the next task from the queue for execution from its work queue which is a circular container for tasks.I suggest the following solution which completely uses functionality existing in the standard library concurrency utils. It uses a
CyclicBarrier
with a task decorator class and a barrier action which re-submits all tasks:ThreadPoolExecutor provides an extension point for afterExecution where you can put the job back at the end of the queue.
You'll have to do a little more work of course to instantiate it yourself without the help of
ExecutorService
's handy factory method, but the constructors are simple enough to grok.You could simply check that all the tasks have been executed and resubmit them once it is the case, like this for example:
EDIT
It seems you want to resubmit a task as soon as it gets completed. You could use an ExecutorCompletionService which enables you to retrieve tasks as and when they get executed, - see below a simple example with 2 tasks that get resubmitted a few times as soon as they are completed. Sample output: