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:48

Have a look at various solutions.

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

  2. ExecutorService#invokeAll()

    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?

  3. CountDownLatch

    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

    How to wait for a thread that spawns it's own thread?

  4. ForkJoinPool or newWorkStealingPool() in Executors

  5. Iterate through all Future objects created after submitting to ExecutorService

查看更多
无与为乐者.
3楼-- · 2018-12-31 20:49

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.

查看更多
皆成旧梦
4楼-- · 2018-12-31 20:49

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();
              }

        }

   }
查看更多
萌妹纸的霸气范
5楼-- · 2018-12-31 20:51

An executor service can be used to manage multiple threads including status and completion. See http://programmingexamples.wikidot.com/executorservice

查看更多
刘海飞了
6楼-- · 2018-12-31 20:52

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.

查看更多
时光乱了年华
7楼-- · 2018-12-31 20:55

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 finshed = es.awaitTermination(1, TimeUnit.MINUTES);
// all tasks have finished or the time has been reached.
查看更多
登录 后发表回答