Reputation: 145
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!
Upvotes: 7
Views: 7931
Reputation: 12206
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.
Upvotes: 7
Reputation: 2199
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
Upvotes: 2
Reputation: 3518
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();
Upvotes: 2
Reputation: 285440
Why not use a CountDownLatch and then notify the main thread when the latch has been completed.
Upvotes: 4
Reputation: 48226
isTerminated()
will do
note however that both awaitTermination
and isTerminated
will only give you a meaningful result after you have called shutdown
Upvotes: 2