问题
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