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
ThreadPoolExecutorbut 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
WorkUnitinstances with aTestExecutor.