ждать, пока все потоки не закончат свою работу в Java - PullRequest
79 голосов
/ 29 октября 2011

Я пишу приложение, в котором есть 5 потоков, которые одновременно получают некоторую информацию из Интернета и заполняют 5 различных полей в классе буфера.
Мне нужно проверить данные буфера и сохранить их в базе данных, когда все потоки закончили свою работу.job.
Как я могу это сделать (получить уведомление, когда все потоки закончили свою работу)?

Ответы [ 16 ]

1 голос
/ 06 мая 2015

попробуйте, сработает.

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

        }

   }
1 голос
/ 29 октября 2011

Служба исполнителя может использоваться для управления несколькими потоками, включая состояние и завершение.Смотри http://programmingexamples.wikidot.com/executorservice

0 голосов
/ 03 июня 2019

Ожидание / блокировка главного потока, пока некоторые другие потоки не завершат свою работу.

Как сказал @Ravindra babu, это может быть достигнуто различными способами, но с примерами.

  • java.lang.Thread. join () С: 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 С: 1,5

    • .countDown() «Уменьшает счетчик группы защелок.
    • .await() «Блок методов ожидания, пока текущий счетчик не достигнет нуля.

    Если вы создали latchGroupCount = 4, тогда countDown() следует вызвать 4 раза, чтобы считать 0. Таким образом, await() освободит блокирующие потоки.

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

Пример кода класса с резьбой LatchTask. Для проверки приближения используйте joiningThreads(); и latchThreads(); из основного метода.

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 Средство синхронизации, которое позволяет всем потокам ожидать друг друга, чтобы достичь общей точки барьера. CyclicBarriers полезны в программах, включающих группу потоков фиксированного размера, которые должны время от времени ожидать Другой. Барьер называется циклическим, поскольку его можно использовать повторно после освобождения ожидающих потоков.
    CyclicBarrier barrier = new CyclicBarrier(3);
    barrier.await();
    
    Например, обратитесь к Concurrent_ParallelNotifyies class.

  • Среда исполнения: мы можем использовать ExecutorService для создания пула потоков и отслеживания хода выполнения асинхронных задач с Future.

    • submit(Runnable), submit(Callable), которые возвращают Future Object. Используя функцию future.get(), мы можем заблокировать основной поток, пока рабочие потоки не завершат свою работу.

    • invokeAll(...) - возвращает список объектов Future, с помощью которого вы можете получить результаты выполнения каждого Callable.

Найдите пример использования интерфейсов Runnable, Callable с платформой Executor.


@ См. Также

0 голосов
/ 02 июня 2019

Я создал небольшой вспомогательный метод для ожидания завершения нескольких потоков:

public static void waitForThreadsToFinish(Thread... threads) {
        try {
            for (Thread thread : threads) {
                thread.join();
            }
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
0 голосов
/ 03 января 2019

Существующие ответы могут join() каждый поток.

Но есть несколько способов получить массив / список потоков:

  • Добавить поток в список при создании..
  • Используйте ThreadGroup для управления потоками.

В следующем коде будет использоваться подход ThreadGruop.Сначала создается группа, затем при создании каждого потока указывается группа в конструкторе, позднее можно было получить массив потоков с помощью 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;
        }
    }
}

Основной поток будет ожидать завершения всех потоков в группе.

0 голосов
/ 07 января 2016

Используйте это в вашем основном потоке: while (! Executor.isTeridity ());Поместите эту строку кода после запуска всех потоков из службы executor.Это запустит основной поток только после завершения всех потоков, запущенных исполнителями.Обязательно вызовите executor.shutdown ();перед вышеупомянутым циклом.

...