ExecutorService, how to know when all threads finished without blocking the main thread?

烈酒焚心 提交于 2020-01-02 03:24:11

问题


I have a multithreaded implementation where i create an ExecutorService and submit tasks to be executed, i want to know when all the threads is submited have finished without blocking the main thread and the UI. I've tried ExecutorService.awaitTermination() but it blocks the main thread and the UI. I've searched alot but i can't seem to find an elegant way of doing this. I'm currently thinking about creating another thread that counts the amount of threads finished and launches an event when they all finished, but that doesn't to be a good approach and i wanted a better solution!


回答1:


Use a SwingWorker to shutdown the thread pool and call awaitTermination(). This will prevent the UI from blocking and call done() from the Event Dispatch Thread on your SwingWorker implementation which you can use to trigger the whatever UI changes you need.

If you desire to keep track of the threads running via a UI update you can use the the worker thread to monitor this in a loop and call publish() with arguments which then get passed to your implementation of process() on the EDT.




回答2:


Why not use a CountDownLatch and then notify the main thread when the latch has been completed.




回答3:


isTerminated() will do

note however that both awaitTermination and isTerminated will only give you a meaningful result after you have called shutdown




回答4:


You can maintain a separate thread to track when the executor service instance shuts down:

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



回答5:


Using CountDownLatch

 

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

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

and within your task (enclose in try / finally)

 latch.countDown();

Or on ExecutorService you call shutdown() and then awaitTermination()

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

Also have a look at THIS answer



来源:https://stackoverflow.com/questions/9779774/executorservice-how-to-know-when-all-threads-finished-without-blocking-the-main

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!