I'm writing an application that has 5 threads that get some information from web simultaneously and fill 5 different fields in a buffer class.
I need to validate buffer data and store it in a database when all threads finished their job.
How can I do this (get alerted when all threads finished their work) ?

- 62,492
- 12
- 87
- 94

- 14,760
- 31
- 112
- 175
-
4*Thread.join* is a rather low-level very Java idiosynchratic way to solve the issue. Moreover it's problematic because the *Thread* API is flawed: you cannot know whether the *join* completed successfuly or not (see *Java Concurrency In Practice*). Higher level abstraction, like using a *CountDownLatch* may be preferrable and will look more natural to programmers who aren't "stuck" in the Java-idiosynchratic mindset. Don't argue with me, go argue with Doug Lea ; ) – Cedric Martin Oct 29 '11 at 13:49
-
possible duplicate of [How to wait for a set of threads to complete?](http://stackoverflow.com/questions/1252190/how-to-wait-for-a-set-of-threads-to-complete) – ChrisF Nov 25 '11 at 14:30
17 Answers
The approach I take is to use an ExecutorService to manage pools of threads.
ExecutorService es = Executors.newCachedThreadPool();
for(int i=0;i<5;i++){
es.execute(new Runnable() { /* your task */ });
}
es.shutdown();
boolean finished = es.awaitTermination(1, TimeUnit.MINUTES);
// all tasks have finished or the time has been reached.

- 60,022
- 51
- 208
- 332

- 525,659
- 79
- 751
- 1,130
-
Be aware that this approach will not work for thread pools as they are not terminated after a set of tasks. – Leonid Oct 11 '13 at 17:03
-
7
-
3
-
3@AquariusPower You could just tell it to wait longer, or forever. – Peter Lawrey Dec 13 '14 at 19:55
-
1oh.. I get it; so I added a message in the loop saying it is waiting all threads to finish; thanks! – Aquarius Power Dec 13 '14 at 19:59
-
What happens if I invoke `awaitTermination` before invoking `es.shutdown()`? E.g. if `es.shutdown()` is invoked from another thread and this may or may not happen before invoking `awaitTermination` on the main thread? – Zoltán Mar 13 '15 at 12:53
-
@Zoltán I suspect it will wait for another thread to shut it down or throw an error. (The Javadoc doesn't say) perhaps you could try it. – Peter Lawrey Mar 15 '15 at 04:30
-
1@PeterLawrey, Is it necessary to call `es.shutdown();`? what if I write a code in which I executed a thread using `es.execute(runnableObj_ZipMaking);` in `try` block and in `finally` I called `boolean finshed = es.awaitTermination(10, TimeUnit.MINUTES);`. So I suppose this should wait until all threads complete their work or timeout is happen (whatever is first), Is my assumption is correct? or call to `shutdown()` is compulsory? – Amogh Sep 07 '15 at 11:25
-
1@Amogh An ExecutorService won't shutdown itself unless it has been GCed. If you do `es.awaitTermination` you will be preventing it from being cleaned up so you will be waiting for another thread to terminate it. – Peter Lawrey Sep 07 '15 at 13:02
-
1@PeterLawrey, Oh this means calling shutdown does not forcefully interrupt the execution of any thread, it will only clean up the completed threads and no new threads/task is accepted and the next line i.e `es.awaitTermination` wait for given time to complete it's execution. – Amogh Sep 07 '15 at 14:26
-
I put a sleep in my threads (6) to simulate blocking, and only the first thread was started. Tried thread.join() that seems to work well. – Gerry May 30 '22 at 16:43
-
@Gerry the shutdown() will prevent any tasks not started from starting. Take it out and increase the timeout to say 10 seconds. – Peter Lawrey Jun 10 '22 at 14:07
You can join
to the threads. The join blocks until the thread completes.
for (Thread thread : threads) {
thread.join();
}
Note that join
throws an InterruptedException
. You'll have to decide what to do if that happens (e.g. try to cancel the other threads to prevent unnecessary work being done).

- 37,698
- 11
- 250
- 211

- 811,555
- 193
- 1,581
- 1,452
-
2
-
4@James Webster: The statement `t.join();` means that the *current thread* blocks until the thread `t` terminates. It does not affect thread `t`. – Mark Byers Oct 29 '11 at 13:50
-
1Thanks. =] Studied paralellism at uni, but that was the sole thing I struggled to learn! Thankfully I don't have to use it much now or when I do it's not too complex or there are no shared resources and blocking isn't critical – James Webster Oct 29 '11 at 14:10
-
1@4r1y4n Whether the code provided is truly parallel depends on what you're trying to do with it, and is related more to aggregating data spread throughout collections using joined threads. You're joining threads, which potentially means "joining" data. Also, parallelism does NOT necessarily mean concurrency. That is dependent on the CPUs. It could very well be that the threads are running in parallel, but the computations are happening in whatever order is determined by the underlying CPU. – Jan 31 '14 at 15:26
-
1
Have a look at various solutions.
join()
API has been introduced in early versions of Java. Some good alternatives are available with this concurrent package since the JDK 1.5 release.
Executes the given tasks, returning a list of Futures holding their status and results when everything is completed.
Refer to this related SE question for code example:
How to use invokeAll() to let all thread pool do their task?
A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
A CountDownLatch is initialized with a given count. The await methods block until the current count reaches zero due to invocations of the
countDown()
method, after which all waiting threads are released and any subsequent invocations of await return immediately. This is a one-shot phenomenon -- the count cannot be reset. If you need a version that resets the count, consider using a CyclicBarrier.
Refer to this question for usage of CountDownLatch here
Iterate through all Future objects created after submitting to
ExecutorService
Source : Various links from docs.oracle.com

- 37,698
- 11
- 250
- 211
Wait/block the Thread Main until some other threads complete their work.
As @Ravindra babu
said it can be achieved in various ways, but showing with examples.
java.lang.Thread.join() Since:1.0
public static void joiningThreads() throws InterruptedException { Thread t1 = new Thread( new LatchTask(1, null), "T1" ); Thread t2 = new Thread( new LatchTask(7, null), "T2" ); Thread t3 = new Thread( new LatchTask(5, null), "T3" ); Thread t4 = new Thread( new LatchTask(2, null), "T4" ); // Start all the threads t1.start(); t2.start(); t3.start(); t4.start(); // Wait till all threads completes t1.join(); t2.join(); t3.join(); t4.join(); }
java.util.concurrent.CountDownLatch Since:1.5
.countDown()
« Decrements the count of the latch group..await()
« The await methods block until the current count reaches zero.
If you created
latchGroupCount = 4
thencountDown()
should be called 4 times to make count 0. So, thatawait()
will release the blocking threads.public static void latchThreads() throws InterruptedException { int latchGroupCount = 4; CountDownLatch latch = new CountDownLatch(latchGroupCount); Thread t1 = new Thread( new LatchTask(1, latch), "T1" ); Thread t2 = new Thread( new LatchTask(7, latch), "T2" ); Thread t3 = new Thread( new LatchTask(5, latch), "T3" ); Thread t4 = new Thread( new LatchTask(2, latch), "T4" ); t1.start(); t2.start(); t3.start(); t4.start(); //latch.countDown(); latch.await(); // block until latchGroupCount is 0. }
Example code of Threaded class LatchTask
. To test the approach use joiningThreads();
and latchThreads();
from main method.
class LatchTask extends Thread {
CountDownLatch latch;
int iterations = 10;
public LatchTask(int iterations, CountDownLatch latch) {
this.iterations = iterations;
this.latch = latch;
}
@Override
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " : Started Task...");
for (int i = 0; i < iterations; i++) {
System.out.println(threadName + " : " + i);
MainThread_Wait_TillWorkerThreadsComplete.sleep(1);
}
System.out.println(threadName + " : Completed Task");
// countDown() « Decrements the count of the latch group.
if(latch != null)
latch.countDown();
}
}
- CyclicBarriers A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.CyclicBarriers are useful in programs involving a fixed sized party of threads that must occasionally wait for each other. The barrier is called cyclic because it can be re-used after the waiting threads are released.
For example refer this Concurrent_ParallelNotifyies class.CyclicBarrier barrier = new CyclicBarrier(3); barrier.await();
Executer framework: we can use ExecutorService to create a thread pool, and tracks the progress of the asynchronous tasks with Future.
submit(Runnable)
,submit(Callable)
which return Future Object. By usingfuture.get()
function we can block the main thread till the working threads completes its work.invokeAll(...)
- returns a list of Future objects via which you can obtain the results of the executions of each Callable.
Find example of using Interfaces Runnable, Callable with Executor framework.
@See also

- 9,250
- 2
- 69
- 74
Apart from Thread.join()
suggested by others, java 5 introduced the executor framework. There you don't work with Thread
objects. Instead, you submit your Callable
or Runnable
objects to an executor. There's a special executor that is meant to execute multiple tasks and return their results out of order. That's the ExecutorCompletionService
:
ExecutorCompletionService executor;
for (..) {
executor.submit(Executors.callable(yourRunnable));
}
Then you can repeatedly call take()
until there are no more Future<?>
objects to return, which means all of them are completed.
Another thing that may be relevant, depending on your scenario is CyclicBarrier
.
A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. CyclicBarriers are useful in programs involving a fixed sized party of threads that must occasionally wait for each other. The barrier is called cyclic because it can be re-used after the waiting threads are released.

- 37,698
- 11
- 250
- 211

- 588,226
- 146
- 1,060
- 1,140
-
This is close, but I'd still make a couple of adjustments. `executor.submit` returns a `Future>`. I would add these futures to a list, and then loop through the list calling `get` on each future. – Ray Oct 31 '11 at 12:41
-
Also, you can instantiate a constructor using `Executors`, e.g., `Executors.newCachedThreadPool` (or similar) – Ray Oct 31 '11 at 12:42
Another possibility is the CountDownLatch
object, which is useful for simple situations : since you know in advance the number of threads, you initialize it with the relevant count, and pass the reference of the object to each thread.
Upon completion of its task, each thread calls CountDownLatch.countDown()
which decrements the internal counter. The main thread, after starting all others, should do the CountDownLatch.await()
blocking call. It will be released as soon as the internal counter has reached 0.
Pay attention that with this object, an InterruptedException
can be thrown as well.

- 37,698
- 11
- 250
- 211

- 487
- 4
- 13
You do
for (Thread t : new Thread[] { th1, th2, th3, th4, th5 })
t.join()
After this for loop, you can be sure all threads have finished their jobs.

- 413,195
- 112
- 811
- 826
Store the Thread-objects into some collection (like a List or a Set), then loop through the collection once the threads are started and call join() on the Threads.

- 37,698
- 11
- 250
- 211

- 15,875
- 5
- 38
- 52
Although not relevant to OP's problem, if you are interested in synchronization (more precisely, a rendez-vous) with exactly one thread, you may use an Exchanger
In my case, I needed to pause the parent thread until the child thread did something, e.g. completed its initialization. A CountDownLatch also works well.

- 37,698
- 11
- 250
- 211

- 16,368
- 4
- 94
- 127
I created a small helper method to wait for a few Threads to finish:
public static void waitForThreadsToFinish(Thread... threads) {
try {
for (Thread thread : threads) {
thread.join();
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}

- 3,025
- 26
- 29
You can use Threadf#join method for this purpose.

- 37,698
- 11
- 250
- 211

- 9,554
- 1
- 28
- 43
try this, will work.
Thread[] threads = new Thread[10];
List<Thread> allThreads = new ArrayList<Thread>();
for(Thread thread : threads){
if(null != thread){
if(thread.isAlive()){
allThreads.add(thread);
}
}
}
while(!allThreads.isEmpty()){
Iterator<Thread> ite = allThreads.iterator();
while(ite.hasNext()){
Thread thread = ite.next();
if(!thread.isAlive()){
ite.remove();
}
}
}

- 11
- 2
I had a similar problem and ended up using Java 8 parallelStream.
requestList.parallelStream().forEach(req -> makeRequest(req));
It's super simple and readable. Behind the scenes it is using default JVM’s fork join pool which means that it will wait for all the threads to finish before continuing. For my case it was a neat solution, because it was the only parallelStream in my application. If you have more than one parallelStream running simultaneously, please read the link below.
More information about parallel streams here.

- 1,005
- 11
- 12
An executor service can be used to manage multiple threads including status and completion. See http://programmingexamples.wikidot.com/executorservice
The existing answers said could join()
each thread.
But there are several ways to get the thread array / list:
- Add the Thread into a list on creation.
- Use
ThreadGroup
to manage the threads.
Following code will use the ThreadGruop
approach. It create a group first, then when create each thread specify the group in constructor, later could get the thread array via ThreadGroup.enumerate()
Code
SyncBlockLearn.java
import org.testng.Assert;
import org.testng.annotations.Test;
/**
* synchronized block - learn,
*
* @author eric
* @date Apr 20, 2015 1:37:11 PM
*/
public class SyncBlockLearn {
private static final int TD_COUNT = 5; // thread count
private static final int ROUND_PER_THREAD = 100; // round for each thread,
private static final long INC_DELAY = 10; // delay of each increase,
// sync block test,
@Test
public void syncBlockTest() throws InterruptedException {
Counter ct = new Counter();
ThreadGroup tg = new ThreadGroup("runner");
for (int i = 0; i < TD_COUNT; i++) {
new Thread(tg, ct, "t-" + i).start();
}
Thread[] tArr = new Thread[TD_COUNT];
tg.enumerate(tArr); // get threads,
// wait all runner to finish,
for (Thread t : tArr) {
t.join();
}
System.out.printf("\nfinal count: %d\n", ct.getCount());
Assert.assertEquals(ct.getCount(), TD_COUNT * ROUND_PER_THREAD);
}
static class Counter implements Runnable {
private final Object lkOn = new Object(); // the object to lock on,
private int count = 0;
@Override
public void run() {
System.out.printf("[%s] begin\n", Thread.currentThread().getName());
for (int i = 0; i < ROUND_PER_THREAD; i++) {
synchronized (lkOn) {
System.out.printf("[%s] [%d] inc to: %d\n", Thread.currentThread().getName(), i, ++count);
}
try {
Thread.sleep(INC_DELAY); // wait a while,
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.printf("[%s] end\n", Thread.currentThread().getName());
}
public int getCount() {
return count;
}
}
}
The main thread will wait for all threads in the group to finish.

- 22,183
- 20
- 145
- 196
I had similar situation , where i had to wait till all child threads complete its execution then only i could get the status result for each of them .. hence i needed to wait till all child thread completed.
below is my code where i did multi-threading using
public static void main(String[] args) {
List<RunnerPojo> testList = ExcelObject.getTestStepsList();//.parallelStream().collect(Collectors.toList());
int threadCount = ConfigFileReader.getInstance().readConfig().getParallelThreadCount();
System.out.println("Thread count is : ========= " + threadCount); // 5
ExecutorService threadExecutor = new DriverScript().threadExecutor(testList, threadCount);
boolean isProcessCompleted = waitUntilCondition(() -> threadExecutor.isTerminated()); // Here i used waitUntil condition
if (isProcessCompleted) {
testList.forEach(x -> {
System.out.println("Test Name: " + x.getTestCaseId());
System.out.println("Test Status : " + x.getStatus());
System.out.println("======= Test Steps ===== ");
x.getTestStepsList().forEach(y -> {
System.out.println("Step Name: " + y.getDescription());
System.out.println("Test caseId : " + y.getTestCaseId());
System.out.println("Step Status: " + y.getResult());
System.out.println("\n ============ ==========");
});
});
}
Below method is for distribution of list with parallel proccessing
// This method will split my list and run in a parallel process with mutliple threads
private ExecutorService threadExecutor(List<RunnerPojo> testList, int threadSize) {
ExecutorService exec = Executors.newFixedThreadPool(threadSize);
testList.forEach(tests -> {
exec.submit(() -> {
driverScript(tests);
});
});
exec.shutdown();
return exec;
}
This is my wait until method: here you can wait till your condition satisfies within do while loop . in my case i waited for some max timeout .
this will keep checking until your threadExecutor.isTerminated()
is true
with polling period of 5 sec.
static boolean waitUntilCondition(Supplier<Boolean> function) {
Double timer = 0.0;
Double maxTimeOut = 20.0;
boolean isFound;
do {
isFound = function.get();
if (isFound) {
break;
} else {
try {
Thread.sleep(5000); // Sleeping for 5 sec (main thread will sleep for 5 sec)
} catch (InterruptedException e) {
e.printStackTrace();
}
timer++;
System.out.println("Waiting for condition to be true .. waited .." + timer * 5 + " sec.");
}
} while (timer < maxTimeOut + 1.0);
return isFound;
}

- 555
- 6
- 17
Use this in your main thread: while(!executor.isTerminated()); Put this line of code after starting all the threads from executor service. This will only start the main thread after all the threads started by executors are finished. Make sure to call executor.shutdown(); before the above loop.

- 1
-
This is active waiting, which will cause CPU to be constantly running an empty loop. Very wasteful. – Adam Michalik Jan 07 '16 at 15:33