wait until all threads finish their work in java

2018-12-31 20:43发布

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) ?

13条回答
若你有天会懂
2楼-- · 2018-12-31 20:55

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.

查看更多
人气声优
3楼-- · 2018-12-31 20:55

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.

查看更多
临风纵饮
4楼-- · 2018-12-31 20:56

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).

查看更多
君临天下
5楼-- · 2018-12-31 21:04

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.

查看更多
栀子花@的思念
6楼-- · 2018-12-31 21:04

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.

查看更多
君临天下
7楼-- · 2018-12-31 21:07

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.

查看更多
登录 后发表回答