ExecutorService,如何知道所有线程何时完成而不阻塞主线程?

时间:2012-03-20 00:09:44

标签: java multithreading swing executorservice

我有一个多线程实现,我创建了一个ExecutorService并提交了要执行的任务,我想知道所有线程被提交的时间已经完成而没有阻塞主线程和UI。我试过了ExecutorService.awaitTermination(),但它阻止了主线程和用户界面。我已经搜索了很多,但我似乎无法找到一种优雅的方式来做到这一点。我目前正在考虑创建另一个线程来计算完成的线程数量,并在它们全部完成时启动一个事件,但这并不是一个好的方法,我想要一个更好的解决方案!

5 个答案:

答案 0 :(得分:7)

使用SwingWorker关闭线程池并调用awaitTermination()。这将阻止UI阻止并从SwingWorker实现上的事件调度线程调用done(),您可以使用它来触发所需的任何UI更改。

如果您希望通过UI更新跟踪运行的线程,可以使用工作线程在循环中监视它,并使用参数调用publish(),然后将参数传递给{{1在美国东部时间。

答案 1 :(得分:4)

为什么不使用CountDownLatch,然后在锁存器完成时通知主线程。

答案 2 :(得分:2)

isTerminated()会做

但请注意,awaitTerminationisTerminated只会在您致电shutdown

后给您一个有意义的结果

答案 3 :(得分: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();

答案 4 :(得分:2)

使用CountDownLatch

 

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

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

并在你的任务中(包含在try / finally中)

 latch.countDown();

或者在ExecutorService上调用shutdown()然后调用awaitTermination()

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

另请查看THIS回答