Как ждать завершения всех потоков, используя ExecutorService? - PullRequest
343 голосов
/ 09 августа 2009

Мне нужно выполнить некоторое количество задач 4 одновременно, что-то вроде этого:

ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
while(...) {
    taskExecutor.execute(new MyTask());
}
//...wait for completion somehow

Как я могу получить уведомление, когда все они будут завершены? Пока я не могу думать о чем-то лучше, чем установить какой-либо глобальный счетчик задач и уменьшить его в конце каждой задачи, а затем отслеживать в бесконечном цикле этот счетчик, чтобы он стал 0; или получить список фьючерсов и в бесконечном цикле монитора isDone для всех из них. Каковы лучшие решения без бесконечных циклов?

Спасибо.

Ответы [ 24 ]

0 голосов
/ 21 февраля 2019

ExecutorService WORKER_THREAD_POOL 
  = Executors.newFixedThreadPool(10);
CountDownLatch latch = new CountDownLatch(2);
for (int i = 0; i < 2; i++) {
    WORKER_THREAD_POOL.submit(() -> {
        try {
            // doSomething();
            latch.countDown();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    });
}

// wait for the latch to be decremented by the two remaining threads
latch.await();

Если doSomething() выдает другие исключения, latch.countDown(), похоже, не будет выполняться, так что мне делать?

0 голосов
/ 31 октября 2014

В executor есть метод getActiveCount() - который подсчитывает количество активных потоков.

После охвата потока мы можем проверить, является ли значение activeCount() 0. Если значение равно нулю, это означает, что в данный момент нет активных потоков, что означает, что задача завершена:

while (true) {
    if (executor.getActiveCount() == 0) {
    //ur own piece of code
    break;
    }
}
0 голосов
/ 29 апреля 2016

Вы можете вызвать waitTillDone () на этом Бегун класс:

Runner runner = Runner.runner(4); // create pool with 4 threads in thread pool

while(...) {
    runner.run(new MyTask()); // here you submit your task
}


runner.waitTillDone(); // and this blocks until all tasks are finished (or failed)


runner.shutdown(); // once you done you can shutdown the runner

Вы можете повторно использовать этот класс и вызывать waitTillDone () столько раз, сколько вы хотите, прежде чем вызывать shutdown (), плюс ваш код очень прост . Также вам не нужно знать число заданий заранее.

Чтобы использовать его, просто добавьте эту зависимость gradle / maven compile 'com.github.matejtymes:javafixes:1.1.1' в ваш проект.

Более подробную информацию можно найти здесь:

https://github.com/MatejTymes/JavaFixes

http://matejtymes.blogspot.com/2016/04/executor-that-notifies-you-when-task.html

0 голосов
/ 22 октября 2015

Это может помочь

Log.i(LOG_TAG, "shutting down executor...");
executor.shutdown();
while (true) {
                try {
                    Log.i(LOG_TAG, "Waiting for executor to terminate...");
                    if (executor.isTerminated())
                        break;
                    if (executor.awaitTermination(5000, TimeUnit.MILLISECONDS)) {
                        break;
                    }
                } catch (InterruptedException ignored) {}
            }
...