2012-03-20 2 views
6

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

+0

Ваш главный поток делает, что он не может быть заблокирован? – EJP

+0

Какой инструмент пользовательского интерфейса вы используете? – Dev

ответ

2

isTerminated() будет делать

к сведению, однако, что оба awaitTermination и isTerminated только даст вам значимый результат после того, как вы назвали shutdown

+0

Я нашел кое-что о isTerminated(), но все же, я думаю, мне нужно запустить его на «боковом потоке», чтобы постоянно проверять, возвращает ли он true, что приводит меня к моему первоначальному решению! – Trota

7

Использовать SwingWorker для отключения пула потоков и вызвать awaitTermination(). Это предотвратит блокировку пользовательского интерфейса и вызовет done() из потока отправки событий в вашей реализации SwingWorker, который вы можете использовать для запуска любых изменений пользовательского интерфейса, которые вам нужны.

Если вы хотите отслеживать потоки, выполняемые с помощью обновления пользовательского интерфейса, вы можете использовать рабочий поток, чтобы отслеживать это в цикле и вызывать publish() с аргументами, которые затем передаются в вашу реализацию process() на EDT.

+1

Он никогда не упоминает, что это приложение Swing, а если нет, то SwingWorker не подходит. –

+1

Я забыл упомянуть, что это приложение Swing! – Trota

+0

Прочитав больше о SwingWorker, я понял, что это довольно простое решение моей проблемы! Спасибо, Дев! – Trota

4

Почему бы не использовать CountDownLatch, а затем уведомить основной поток, когда защелка выполнена.

+1

Хорошая идея; есть хороший пример, цитируемый [здесь] (http://stackoverflow.com/a/3588523/230513). – trashgod

+1

@trashgod просто прокомментировал ваше сообщение: пример имеет небольшой сбой при доступе к textComponent от EDT – kleopatra

2

Вы можете создать отдельный поток для отслеживания, когда экземпляр службы исполнитель выключается:

final ExecutorService execSvc = ...; 
    execSvc.submit(task1); 
    ... 
    execSvc.submit(taskN); 
    // important to request the exec service to shut down :) 
    execSvc.shutdown(); 

    new Thread(new Runnable() { 

     public void run() { 
      while (!execSvc.isTerminated()) { 
       try { 
        execSvc.awaitTermination(60, TimeUnit.SECONDS); 
       } catch (InterruptedException e) { 
        // ignore exception 
       } 
      } 
      System.out.println("ExecSvc.run: exec service has terminated!"); 
      // possibly submit a task using SwingUtilities.invokeLater() to update the UI 
     } 

    }).start(); 
2

Использование CountDownLatch

 

CountDownLatch latch = new CountDownLatch(totalNumberOfTasks); 
ExecutorService taskExecutor = Executors.newFixedThreadPool(4); 
while(...) { 
    taskExecutor.execute(new MyTask()); 
} 

try { 
    latch.await(); 
} catch (InterruptedException E) { 
    // handle 
} 

и в пределах вашей задачи (вложить в попытке /, наконец)

 latch.countDown(); 

Или на ExecutorService вы вызываете shutdown(), а затем awa itTermination()

 
ExecutorService taskExecutor = Executors.newFixedThreadPool(4); 
while(...) { 
    taskExecutor.execute(new MyTask()); 
} 
taskExecutor.shutdown(); 
try { 
    taskExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); 
} catch (InterruptedException e) { 
    ... 
} 

Кроме того, есть взгляд на THIS ответ

+0

Если я не ошибаюсь в своем понимании, ни одно из этих решений не затрагивает фундаментальный вопрос OP, который заключается в том, чтобы избежать блокировки основного нить. – Trevor

Смежные вопросы