I have an unbounded queue of jobs which can be processed asynchronously. The processing of each job may or may not trigger the creation of new jobs for this queue.
I would like a pool of several worker threads to take items from this queue and process them in parallel, until both the queue is empty and all worker threads are idle waiting for new jobs on the queue (as a busy worker could end up adding new jobs to the queue).
Is there a recipe for using the java.util.concurrent
implementations which I can use to solve this particular problem, where workers are also producers? It is not clear that such a scenario is supported in a straightforward manner from the APIs.
In particular, I want to be able to detect the termination condition, namely, when no more jobs are available (empty job queue) and there will be no more jobs produced (all idle worker threads).
EDIT
Nam San's answer below appears to be the most elegant approach, which basically boiled down to tracking the number of submitted jobs vs. the number of completed jobs, and using the case where these numbers were equal as the termination condition.
I've implemented a full example using java.util.concurrent
implementations which extends ThreadPoolExecutor
to achieve this, plus specialises the job queue to accept Comparable
instances which are sorted in a particular way.
- TestExecutor.java: A custom executor which extends
ThreadPoolExecutor
but has additional methods to execute jobs which may create new jobs, and a new await method which waits until all submitted jobs are complete. - WorkUnit.java: An example of a comparable, runnable job which may create new jobs to submit to
TestExecutor
. - Test.java: Contains a main method to run an example using
WorkUnit
instances with aTestExecutor
.