ExecutorService, how do I know when all threads are finished without blocking the main thread?

I have a multi-threaded implementation, where I create an ExecutorService and send tasks that are running, I want to know when all threads are sent, completed without blocking the main thread and the user interface. I tried ExecutorService.awaitTermination() , but it blocks the main thread and user interface. I searched a lot, but I cannot find an elegant way to do this. I'm currently thinking of creating another thread that counts the number of threads completed and fires an event when everything is over, but this is not a good approach, and I wanted to get a better solution!

+6
source share
5 answers

Use SwingWorker to close the thread pool and call awaitTermination() . This will prevent UI blocking and call done() from the Dispatch event stream in your SwingWorker implementation, which you can use to trigger any UI changes you need.

If you want to keep track of the threads executed by updating the user interface, you can use a workflow to control this in a loop and call publish() with arguments, which are then passed to your process() implementation on the EDT.

+7
source

Why not use a CountDownLatch, and then notify the main thread when the latch is completed.

+4
source

isTerminated() will execute

note, however, that both awaitTermination and isTerminated will only give you meaningful results after you call shutdown

+2
source

You can maintain a separate thread for tracking when an instance of the executor service is shut 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(); 
+2
source

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 inside your task (enclose in try / finally)

  latch.countDown ();

Or in ExecutorService you call shutdown () and then expect Termination ()

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

Also see THIS answer

+2
source

Source: https://habr.com/ru/post/911155/


All Articles