I have a pipeline of tasks (each task in the pipeline has different parallelism requirements), each task works in a different ExecutorService. Tasks work on packets of data, so if we have 10 datapackets then 10 tasks will be submitted to service1, one task per data packet. Once a task submitted to service1 has actually invoked it may submit a new task to work further on the datapacket to service2, service3 or not.
The following code works fine, i.e.:
shutdown()is invoked onservice1after everything has been submitted toservice1-
Then awaitTermination() does not return until all the tasks that were submitted before the shutdown() have actually completed running.
—shutdown()is then invoked onservice2but because all tasks submitted toservice1have completed, and all tasks are submitted toservice2from tasks onservice1all tasks have been submitted toservice2beforeshutdown()is called onservice2.
— and so on forservice3ExecutorService[] services = { service1, service2, service3}; int count = 0; for(ExecutorService service: services) { service.shutdown(); service.awaitTermination(1, TimeUnit.HOURS); }
However I have now added a case whereby service2 can break a datapacket into a smaller packet and submit additional tasks on service2 and the code is now failing. The problem is that shutdown() is called on service2 once all the tasks on service1 have completed, but now we want to submit additional service2 tasks from a task running in service2
My questions:
- Does
shutdown()rerun after all submitted tasks have finished running, or does it return immediately but just doesn’t stop already submitted tasks from running ? Update:answered below - How do I solve my new problem ?
Matts question looks like it may well work but Im concerned it may cause new issues.
Ive come up with a solution which works without many code changes for my scenario, although it seems a bit clunky
Ive introduced a new service (service2a) that runs the same task as service2. When a task in service2 wants to submit a small data packet it submits it to service2a rather than service2 so all sub packets are submitted to service2a before service 2 shutdowns. This works for me as the smaller data packets dont need to be broken down into further subpackets and the subpackets idea only applies to service2(a) not any of the other services.