Search code examples
javamultithreadingconcurrencyjava.util.concurrent

Non-blocking method to start several threads and run a callabck on the parent thread when all children have finished


The main thing is that the callback should be on the PARENT thread and not called from the task, which is finishing the job (e.g. NOT like ThreadPoolExecutor's afterExecute() hook). I'd like to have something like:

ExecutorService exec = Executors.newSingleThreadExecutor();
>>>>> exec.addAllJobsFinishedListener(someListener) <<<<<
exec.submit(task);

and someListener to have an Overrideable method like allJobsFinished()


Solution

  • Non-blocking method to start several threads and run a callback on the parent thread when all children have finished

    If you want the callback on PARENT thread, then I'm afraid you need to have the parent thread calling exec.awaitTermination(...). After you have submitted all of the jobs and the exec.shutdown() has been called, this waits for the all of the jobs in the thread-pool to complete. If you want this to be non-blocking then you are going to have to do this in another thread (running in a different pool of course).

    I don't see how it can be a "listener" running on the parent thread that is also non-blocking. You could have a background thread checking which will update some sort of shared state (like an AtomicBoolean) to be true when the exec.awaitTermination(...) completes.

    ThreadPoolExecutor does have terminate() method that you can override. Is that not what you want? Here are the javadocs for the method. Your code would look something like:

    ThreadPoolExecutor threadPool =
       new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS,
          new LinkedBlockingQueue()) {
         public void terminated() {
            super.terminated();
            // do something magic
         }
    };
    threadPool.execute(task);
    // ...
    // need to shutdown the pool after you've submitted all of the tasks
    threadPool.shutdown();
    

    If the "something magic" code set a shared volatile boolean or an AtomicBoolean that the main thread could check, then it should work fine.