During the course of my program execution, a number of threads are started. The amount of threads varies depending on user defined settings, but they are all executing the same method with different variables.
In some situations, a clean up is required mid execution, part of this is stopping all the threads, I don't want them to stop immediately though, I just set a variable that they check for that terminates them. The problem is that it can be up to 1/2 second before the thread stops. However, I need to be sure that all threads have stopped before the clean up can continues. The cleanup is executed from another thread so technically I need this thread to wait for the other threads to finish.
I have thought of several ways of doing this, but they all seem to be overly complex. I was hoping there would be some method that can wait for a group of threads to complete. Does anything like this exist?
Thanks.
Have you seen the
Executor
classes injava.util.concurrent
? You could run your threads through anExecutorService
. It gives you a single object you can use to cancel the threads or wait for them to complete.If you control the creation of the Threads (submission to an ExecutorService) then it appears you can use an
ExecutorCompletionService
see ExecutorCompletionService? Why do need one if we have invokeAll? for various answers there.If you don't control thread creation, here is an approach that allows you to join the threads "one by one as they finish" (and know which one finishes first, etc.), inspired by the ruby ThreadWait class. Basically by newing up "watching threads" which alert when the other threads terminate, you can know when the "next" thread out of many terminates.
You'd use it something like this:
And the source:
The nice part of this is that it works with generic Java threads, without modification, any thread can be joined. The caveat is it requires some extra thread creation. Also this particular implementation "leaves threads behind" if you don't call joinNextThread() the full number of times, and doesn't have an "close" method, etc. Comment here if you'd like a more polished version created. You could also use this same type of pattern with "Futures" instead of Thread objects, etc.
Just join them one by one:
(You'll need to do something with
InterruptedException
, and you may well want to provide a time-out in case things go wrong, but that's the basic idea...)Define a utility method (or methods) yourself:
Or you may have an array
Alternatively you could look at using a
CyclicBarrier
in thejava.util.concurrent
library to implement an arbitrary rendezvous point between multiple threads.If you are using java 1.5 or higher, you can try CyclicBarrier. You can pass the cleanup operation as its constructor parameter, and just call
barrier.await()
on all threads when there is a need for cleanup.