407

I need to execute some amount of tasks 4 at a time, something like this:

ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
while(...) {
    taskExecutor.execute(new MyTask());
}
//...wait for completion somehow

How can I get notified once all of them are complete? For now I can't think about anything better than setting some global task counter and decrease it at the end of every task, then monitor in infinite loop this counter to become 0; or get a list of Futures and in infinite loop monitor isDone for all of them. What are better solutions not involving infinite loops?

Thanks.

bluish
  • 23,093
  • 23
  • 110
  • 171
serg
  • 103,023
  • 70
  • 299
  • 324

26 Answers26

473

Basically on an 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) {
  ...
}
Ravindra babu
  • 42,401
  • 8
  • 208
  • 194
cletus
  • 578,732
  • 155
  • 890
  • 933
  • 1
    Looks nice and simple, only I have feeling that shutdown here is used not for what it was designed (or it is fine?). – serg Aug 09 '09 at 05:15
  • 1
    It's a common pattern. Transient threadpools like the above are good for several reasons and I pretty much always prefer them to persistent threadpools where a lot more can go wrong or at least it can be harder to figure out. The above is really straightforward which is why I like it. – cletus Aug 09 '09 at 05:29
  • 9
    this is exactly what shutdown / awaitTermination are meant for – matt b Aug 09 '09 at 14:31
  • 33
    It is a good pattern if this task handling is a one-time event. If this is done repeatedly during the same runtime, however, it is not optimal, as you would create and tear down threads repeatedly every time it is executed. – sjlee Aug 09 '09 at 16:25
  • 1
    This pattern is **incomplete**: Some unsubmitted tasks may be never executed. – 象嘉道 Jul 24 '11 at 22:47
  • 1
    @Kejia It is not incomplete... Think about it this way: Your main thread is spawning off subthreads in a loop. When it's done adding, you run this code. **You might see output out of order**, but all of your tasks will have been spun off. Thanks @Cletus! – inanutshellus Aug 17 '11 at 15:32
  • 47
    I'm looking for any official documentation that `Long.MAX_VALUE, TimeUnit.NANOSECONDS` is equivalent to not having a timeout. – Sam Harwell Aug 22 '12 at 14:04
  • 1
    @serg is this still considered the best answer over using `invokeAll()` as proposed by sjlee? – Brad Aug 27 '12 at 21:35
  • 17
    I can't believe that you have to use shutdown in order to join on all the current threads (after using shutdown, you cannot use the executor again ever). Suggest using list of Future's instead... – rogerdpack Nov 02 '12 at 16:02
  • 2
    As I'm testing this out I found that the executor finishes before all tasks have completed. If I use Thread.sleep(100) before calling shutdown() it works. So I suspect that there may be some timing issues with your code if the time between adding tasks to the shutdown call is too small. – jontejj May 14 '13 at 17:47
  • 2
    this wont work if you dont want to shutdown the executor. For a perpetually running batch kind of thing u need to submit jobs and wait for them to finish before jumping ahead. In Such a case a latch or a barrier makes more sense than a shutdown. – Nazgul Nov 11 '13 at 15:25
  • 4
    IMO it's probably not a wise thing to NOT have a timeout. There's always a likelihood your task is stuck / deadlocking and the user would wait forever. – gerrytan Jan 28 '14 at 02:10
  • 1
    @ashutosh I can't find any documentation on this. It appears to be a method of a Spring library, and not plain Java functionality. – Zero3 May 14 '15 at 20:23
  • 22
    @SamHarwell see the `java.util.concurrent` package [documentation](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html) under the `Timing` section: *To wait "forever", you can use a value of `Long.MAX_VALUE`* – beluchin Aug 28 '15 at 22:01
  • @ashutosh 1) That requires *springframework*. 2) Doesn't look any simpler to me than shutdown/awaitTermination. – ToolmakerSteve Sep 06 '15 at 09:35
  • Is it better than using infinite loop while checking isTerminated() ? – Praveen Kumar Jan 06 '16 at 06:50
  • If I don't want to shutdown because I want to keep my executor alive. How can I know the maximum number of pending tasks that could I have there? – Sergio Bilello Apr 05 '16 at 20:49
  • 1
    @SamHarwell `TimeUnit.NANOSECONDS` and `Long.MAX_VALUE` equals 106,751 Days or 292 years (`TimeUnit.NANOSECONDS.toDays(Long.MAX_VALUE);`), that should be enough, or use some of the bigger TimeUnits. – hinneLinks Dec 09 '16 at 07:51
  • When sizing thread pools, it is often useful to base the size on the number of logical cores in the machine running the application. In Java, you can get that value by calling Runtime.getRuntime().availableProcessors(). In this case, it would be Math.min(4, Runtime.getRuntime().availableProcessors()); – eli-bd Jun 24 '17 at 16:23
  • 2
    executor.shutdown(); is stopping my program !! – Jobs May 07 '18 at 18:40
  • Java apis are pretty terrible. Thank you for this insight. – Mobigital Aug 02 '19 at 19:34
  • @cletus is awaitTermination() necessary after shutdown()? – Gaurav Oct 11 '19 at 11:04
182

Use a 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();
Ravindra babu
  • 42,401
  • 8
  • 208
  • 194
ChssPly76
  • 94,877
  • 24
  • 194
  • 191
  • 3
    There aren't 4 tasks. There are "some number of tasks" done 4 at a time. – cletus Aug 09 '09 at 04:55
  • Only instead of CountDownLatch(4) I need to use number of total threads created, right? – serg Aug 09 '09 at 04:55
  • 2
    Sorry, I misunderstood the question. Yes, number of tasks should be the argument to CountDownLatch constructor – ChssPly76 Aug 09 '09 at 04:56
  • 4
    I find this solution more elegant than the others, it looks like it was made for this purpose, and it's simple and straightforward. – wvdschel Aug 09 '09 at 08:00
  • 3
    What if you don't know the number of tasks before you start? – cletus Aug 09 '09 at 10:26
  • 11
    @cletus - then you don't use a CountDownLatch :-) Mind you, I'm not arguing that this approach is better than yours. However, I found that in real life scenarios I _do_ know the number of tasks, thread pool settings _do_ need to be configurable per deployment, and pools _can_ be reused. So I usually have thread pools injected by Spring and setting them as prototypes and manually shutting them down **only** in order to wait for threads to finish seems less than ideal. – ChssPly76 Aug 09 '09 at 16:15
  • This does seem to be better than `shutdown`/`awaitTermination`. `CyclicBarrier` also seems to be useful when you need to run threads in groups at a time. – Andrew Mao Dec 30 '12 at 05:24
  • 1
    stryba's Semaphore solution is more flexible, as it accomplishes the same result (no need to shutdown) as CountDownLatch, without needing to know how many tasks there are. – ToolmakerSteve Sep 06 '15 at 09:39
  • +1,thanks it helped, also referred this http://howtodoinjava.com/core-java/interviews-questions/when-to-use-countdownlatch-java-concurrency-example-tutorial/ – Saurabh Feb 04 '16 at 10:13
  • Another major advantage of this approach is that it works with shared `Executor`s that cannot simply be shut down because they are used by others. – Gili Jan 06 '18 at 08:53
85

ExecutorService.invokeAll() does it for you.

ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
List<Callable<?>> tasks; // your tasks
// invokeAll() returns when all tasks are complete
List<Future<?>> futures = taskExecutor.invokeAll(tasks);
Ravindra babu
  • 42,401
  • 8
  • 208
  • 194
sjlee
  • 7,266
  • 1
  • 22
  • 35
  • The difficulty comes if/when you have the start the "4" threads one at a time, piece-wise, then join/let finish all 4... – rogerdpack Nov 08 '12 at 22:44
  • @rogerdpack: I am still learning this executors and stuff. But in response to what you ask. Should the 4 threads at a time not be part of a batch task which is executed using the answer above? – Mukul Goel Nov 20 '14 at 16:39
  • 3
    This method will only work if you know the number of tasks before hand. – Konstantin Jan 26 '15 at 12:37
  • 3
    I think that when the `futures` are returned, the tasks haven't been completed. They might complete in the future and you'll have a link to the result. That's why it's called a `Future`. You have the method [Future.get()](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Future.html#get--), which will wait for the task to finish to get a result. – AlikElzin-kilaka Nov 13 '16 at 11:46
  • 8
    @AlikElzin-kilaka Quote from the JavaDocs (linked in the answer): "Executes the given tasks, returning a list of Futures holding their status and results when all complete. Future.isDone() is true for each element of the returned list." – Hulk Sep 07 '17 at 07:27
  • 2
    Note that executorService.invokeAll will wait for all threads to complete, but you will still need to call executorService.shutdown to clean up your thread pool. – The Gilbert Arenas Dagger Jan 04 '19 at 15:54
48

You can use Lists of Futures, as well:

List<Future> futures = new ArrayList<Future>();
// now add to it:
futures.add(executorInstance.submit(new Callable<Void>() {
  public Void call() throws IOException {
     // do something
    return null;
  }
}));

then when you want to join on all of them, its essentially the equivalent of joining on each, (with the added benefit that it re-raises exceptions from child threads to the main):

for(Future f: this.futures) { f.get(); }

Basically the trick is to call .get() on each Future one at a time, instead of infinite looping calling isDone() on (all or each). So you're guaranteed to "move on" through and past this block as soon as the last thread finishes. The caveat is that since the .get() call re-raises exceptions, if one of the threads dies, you would raise from this possibly before the other threads have finished to completion [to avoid this, you could add a catch ExecutionException around the get call]. The other caveat is it keeps a reference to all threads so if they have thread local variables they won't get collected till after you get past this block (though you might be able to get around this, if it became a problem, by removing Future's off the ArrayList). If you wanted to know which Future "finishes first" you could use some something like https://stackoverflow.com/a/31885029/32453

Community
  • 1
  • 1
rogerdpack
  • 50,731
  • 31
  • 212
  • 332
40

In Java8 you can do it with CompletableFuture:

ExecutorService es = Executors.newFixedThreadPool(4);
List<Runnable> tasks = getTasks();
CompletableFuture<?>[] futures = tasks.stream()
                               .map(task -> CompletableFuture.runAsync(task, es))
                               .toArray(CompletableFuture[]::new);
CompletableFuture.allOf(futures).join();    
es.shutdown();
AdamSkywalker
  • 10,723
  • 2
  • 33
  • 71
  • 3
    This is a very elegant solution. – mattvonb Feb 13 '18 at 22:51
  • `ExecutorService es = Executors.newFixedThreadPool(4); List< Future> futures = new ArrayList<>(); for(Runnable task : taskList) { futures.add(es.submit(task)); } for(Future future : futures) { try { future.get(); }catch(Exception e){ // do logging and nothing else } }` – user2862544 Sep 02 '18 at 16:06
  • @AdamSkywalker is awaitTermination() necessary after es.shutdown()? – Gaurav Oct 11 '19 at 11:05
  • @gaurav when you call shutdown, some tasks may not be finished yet. So awaitTermination will block the calling thread until everything is done. It depends on whether you need to wait for results in this thread or not. – AdamSkywalker Oct 11 '19 at 12:36
  • @AdamSkywalker great answer. makes sense to not call awaitTermination() if I dont need to wait for the results. – Gaurav Oct 11 '19 at 12:39
  • @AdamSkywalker Great answer!! Elegant! – nagendra547 Oct 25 '19 at 02:25
27

Just my two cents. To overcome the requirement of CountDownLatch to know the number of tasks beforehand, you could do it the old fashion way by using a simple Semaphore.

ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
int numberOfTasks=0;
Semaphore s=new Semaphore(0);
while(...) {
    taskExecutor.execute(new MyTask());
    numberOfTasks++;
}

try {
    s.aquire(numberOfTasks);
...

In your task just call s.release() as you would latch.countDown();

stryba
  • 1,924
  • 13
  • 18
  • On seeing this, I first wondered if it would be a problem if some `release` calls happen before the `acquire` call, but after reading Semaphore documentation, I see that is okay. – ToolmakerSteve Sep 06 '15 at 09:27
13

A bit late to the game but for the sake of completion...

Instead of 'waiting' for all tasks to finish, you can think in terms of the Hollywood principle, "don't call me, I'll call you" - when I'm finished. I think the resulting code is more elegant...

Guava offers some interesting tools to accomplish this.

An example:

Wrap an ExecutorService into a ListeningExecutorService:

ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));

Submit a collection of callables for execution ::

for (Callable<Integer> callable : callables) {
  ListenableFuture<Integer> lf = service.submit(callable);
  // listenableFutures is a collection
  listenableFutures.add(lf)
});

Now the essential part:

ListenableFuture<List<Integer>> lf = Futures.successfulAsList(listenableFutures);

Attach a callback to the ListenableFuture, that you can use to be notified when all futures complete:

Futures.addCallback(lf, new FutureCallback<List<Integer>> () {
    @Override
    public void onSuccess(List<Integer> result) {
        // do something with all the results
    }

    @Override
    public void onFailure(Throwable t) {
        // log failure
    }
});

This also offers the advantage that you can collect all the results in one place once the processing is finished...

More information here

Răzvan Petruescu
  • 725
  • 1
  • 7
  • 16
  • 2
    Very clean. Does work flawlessly even on Android. Just had to use `runOnUiThread()` in `onSuccess()`. – DSchmidt Feb 20 '17 at 22:40
12

The CyclicBarrier class in Java 5 and later is designed for this sort of thing.

Ravindra babu
  • 42,401
  • 8
  • 208
  • 194
Pekka Enberg
  • 371
  • 2
  • 5
  • 7
    Cool, can never remember the name of this data structure. However, only suitable if you know beforehand the amount of tasks that will get queued. – ᆼᆺᆼ Jan 02 '12 at 08:16
  • yeah you'd think you'd be able to hit the barrier with the current thread, and all the child threads, then when you passed it you'd know the child threads were done... – rogerdpack Nov 08 '12 at 22:45
  • Actually it is wrong answer. CyclicBarrier designed for portions. CountDownLatch designed for waiting event – gstackoverflow Feb 16 '17 at 13:43
8

here is two options , just bit confuse which one is best to go.

Option 1:

ExecutorService es = Executors.newFixedThreadPool(4);
List<Runnable> tasks = getTasks();
CompletableFuture<?>[] futures = tasks.stream()
                               .map(task -> CompletableFuture.runAsync(task, es))
                               .toArray(CompletableFuture[]::new);
CompletableFuture.allOf(futures).join();    
es.shutdown();

Option 2:

ExecutorService es = Executors.newFixedThreadPool(4);
List< Future<?>> futures = new ArrayList<>();
for(Runnable task : taskList) {
    futures.add(es.submit(task));
}

for(Future<?> future : futures) {
    try {
        future.get();
    }catch(Exception e){
        // do logging and nothing else
    }
}
es.shutdown();

Here putting future.get(); in try catch is good idea right?

user2862544
  • 375
  • 2
  • 10
7

Follow one of below approaches.

  1. Iterate through all Future tasks, returned from submit on ExecutorService and check the status with blocking call get() on Future object as suggested by Kiran
  2. Use invokeAll() on ExecutorService
  3. CountDownLatch
  4. ForkJoinPool or Executors.html#newWorkStealingPool
  5. Use shutdown, awaitTermination, shutdownNow APIs of ThreadPoolExecutor in proper sequence

Related SE questions:

How is CountDownLatch used in Java Multithreading?

How to properly shutdown java ExecutorService

Jonathan
  • 18,696
  • 6
  • 62
  • 66
Ravindra babu
  • 42,401
  • 8
  • 208
  • 194
5

You could wrap your tasks in another runnable, that will send notifications:

taskExecutor.execute(new Runnable() {
  public void run() {
    taskStartedNotification();
    new MyTask().run();
    taskFinishedNotification();
  }
});
Zed
  • 53,338
  • 7
  • 71
  • 100
  • 1
    Took me awhile to see how this would solve OP's question. First, note that this wrapping is of *each* task, not of the code that starts all the tasks. Presumably, each start would increment a counter, and each finish would decrement that counter, or would increment a `completed` counter. So after starting them all, at each notification, could determine whether **all** tasks have completed. Note that it is vital to use `try/finally` so that a finished notification (or an alternative notification in `catch` block) is given even if a task fails. Otherwise, would wait forever. – ToolmakerSteve Sep 06 '15 at 09:12
3

I've just written a sample program that solves your problem. There was no concise implementation given, so I'll add one. While you can use executor.shutdown() and executor.awaitTermination(), it is not the best practice as the time taken by different threads would be unpredictable.

ExecutorService es = Executors.newCachedThreadPool();
    List<Callable<Integer>> tasks = new ArrayList<>();

    for (int j = 1; j <= 10; j++) {
        tasks.add(new Callable<Integer>() {

            @Override
            public Integer call() throws Exception {
                int sum = 0;
                System.out.println("Starting Thread "
                        + Thread.currentThread().getId());

                for (int i = 0; i < 1000000; i++) {
                    sum += i;
                }

                System.out.println("Stopping Thread "
                        + Thread.currentThread().getId());
                return sum;
            }

        });
    }

    try {
        List<Future<Integer>> futures = es.invokeAll(tasks);
        int flag = 0;

        for (Future<Integer> f : futures) {
            Integer res = f.get();
            System.out.println("Sum: " + res);
            if (!f.isDone()) 
                flag = 1;
        }

        if (flag == 0)
            System.out.println("SUCCESS");
        else
            System.out.println("FAILED");

    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }
Kiran
  • 1,026
  • 1
  • 11
  • 24
  • It is good that you show use of future.get -- good alternative to know about. But why do you consider it better to wait **forever**, than to set some maximum acceptable timeout? More importantly, there is no reason to do all this logic, when one can simply give a really, really long time to awaitTermination, if you want to wait (essentially forever) until all tasks complete. – ToolmakerSteve Sep 06 '15 at 09:20
  • This is not different from already presented solutions here. Your just solution is the same as presented by @sjlee – Manish Kumar Sharma Jun 12 '17 at 05:20
  • Not sure why you need to check for done when according to oracle doc, invokeAll will return only "when all complete or the timeout expires, whichever happens first" – Mashrur Nov 30 '17 at 06:13
3

Just to provide more alternatives here different to use latch/barriers. You can also get the partial results until all of them finish using CompletionService.

From Java Concurrency in practice: "If you have a batch of computations to submit to an Executor and you want to retrieve their results as they become available, you could retain the Future associated with each task and repeatedly poll for completion by calling get with a timeout of zero. This is possible, but tedious. Fortunately there is a better way: a completion service."

Here the implementation

public class TaskSubmiter {
    private final ExecutorService executor;
    TaskSubmiter(ExecutorService executor) { this.executor = executor; }
    void doSomethingLarge(AnySourceClass source) {
        final List<InterestedResult> info = doPartialAsyncProcess(source);
        CompletionService<PartialResult> completionService = new ExecutorCompletionService<PartialResult>(executor);
        for (final InterestedResult interestedResultItem : info)
            completionService.submit(new Callable<PartialResult>() {
                public PartialResult call() {
                    return InterestedResult.doAnOperationToGetPartialResult();
                }
        });

    try {
        for (int t = 0, n = info.size(); t < n; t++) {
            Future<PartialResult> f = completionService.take();
            PartialResult PartialResult = f.get();
            processThisSegment(PartialResult);
            }
        } 
        catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } 
        catch (ExecutionException e) {
            throw somethinghrowable(e.getCause());
        }
    }
}
3

This is my solution, based in "AdamSkywalker" tip, and it works

package frss.main;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestHilos {

    void procesar() {
        ExecutorService es = Executors.newFixedThreadPool(4);
        List<Runnable> tasks = getTasks();
        CompletableFuture<?>[] futures = tasks.stream().map(task -> CompletableFuture.runAsync(task, es)).toArray(CompletableFuture[]::new);
        CompletableFuture.allOf(futures).join();
        es.shutdown();

        System.out.println("FIN DEL PROCESO DE HILOS");
    }

    private List<Runnable> getTasks() {
        List<Runnable> tasks = new ArrayList<Runnable>();

        Hilo01 task1 = new Hilo01();
        tasks.add(task1);

        Hilo02 task2 = new Hilo02();
        tasks.add(task2);
        return tasks;
    }

    private class Hilo01 extends Thread {

        @Override
        public void run() {
            System.out.println("HILO 1");
        }

    }

    private class Hilo02 extends Thread {

        @Override
        public void run() {
            try {
                sleep(2000);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("HILO 2");
        }

    }


    public static void main(String[] args) {
        TestHilos test = new TestHilos();
        test.procesar();
    }
}
3

Clean way with ExecutorService

 List<Future<Void>> results = null;
 try {
     List<Callable<Void>> tasks = new ArrayList<>();
     ExecutorService executorService = Executors.newFixedThreadPool(4);
     results = executorService.invokeAll(tasks);
 } catch (InterruptedException ex) {
     ...
 } catch (Exception ex) {
     ...
 }
shubham
  • 101
  • 6
2

You could use this code:

public class MyTask implements Runnable {

    private CountDownLatch countDownLatch;

    public MyTask(CountDownLatch countDownLatch {
         this.countDownLatch = countDownLatch;
    }

    @Override
    public void run() {
         try {
             //Do somethings
             //
             this.countDownLatch.countDown();//important
         } catch (InterruptedException ex) {
              Thread.currentThread().interrupt();
         }
     }
}

CountDownLatch countDownLatch = new CountDownLatch(NUMBER_OF_TASKS);
ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
for (int i = 0; i < NUMBER_OF_TASKS; i++){
     taskExecutor.execute(new MyTask(countDownLatch));
}
countDownLatch.await();
System.out.println("Finish tasks");
Tuan Pham
  • 601
  • 9
  • 8
2

So I post my answer from linked question here, incase someone want a simpler way to do this

ExecutorService executor = Executors.newFixedThreadPool(10);
CompletableFuture[] futures = new CompletableFuture[10];
int i = 0;
while (...) {
    futures[i++] =  CompletableFuture.runAsync(runner, executor);
}

CompletableFuture.allOf(futures).join(); // THis will wait until all future ready.
Mạnh Quyết Nguyễn
  • 15,590
  • 1
  • 17
  • 41
2

I created the following working example. The idea is to have a way to process a pool of tasks (I am using a queue as example) with many Threads (determined programmatically by the numberOfTasks/threshold), and wait until all Threads are completed to continue with some other processing.

import java.util.PriorityQueue;
import java.util.Queue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/** Testing CountDownLatch and ExecutorService to manage scenario where
 * multiple Threads work together to complete tasks from a single
 * resource provider, so the processing can be faster. */
public class ThreadCountDown {

private CountDownLatch threadsCountdown = null;
private static Queue<Integer> tasks = new PriorityQueue<>();

public static void main(String[] args) {
    // Create a queue with "Tasks"
    int numberOfTasks = 2000;
    while(numberOfTasks-- > 0) {
        tasks.add(numberOfTasks);
    }

    // Initiate Processing of Tasks
    ThreadCountDown main = new ThreadCountDown();
    main.process(tasks);
}

/* Receiving the Tasks to process, and creating multiple Threads
* to process in parallel. */
private void process(Queue<Integer> tasks) {
    int numberOfThreads = getNumberOfThreadsRequired(tasks.size());
    threadsCountdown = new CountDownLatch(numberOfThreads);
    ExecutorService threadExecutor = Executors.newFixedThreadPool(numberOfThreads);

    //Initialize each Thread
    while(numberOfThreads-- > 0) {
        System.out.println("Initializing Thread: "+numberOfThreads);
        threadExecutor.execute(new MyThread("Thread "+numberOfThreads));
    }

    try {
        //Shutdown the Executor, so it cannot receive more Threads.
        threadExecutor.shutdown();
        threadsCountdown.await();
        System.out.println("ALL THREADS COMPLETED!");
        //continue With Some Other Process Here
    } catch (InterruptedException ex) {
        ex.printStackTrace();
    }
}

/* Determine the number of Threads to create */
private int getNumberOfThreadsRequired(int size) {
    int threshold = 100;
    int threads = size / threshold;
    if( size > (threads*threshold) ){
        threads++;
    }
    return threads;
}

/* Task Provider. All Threads will get their task from here */
private synchronized static Integer getTask(){
    return tasks.poll();
}

/* The Threads will get Tasks and process them, while still available.
* When no more tasks available, the thread will complete and reduce the threadsCountdown */
private class MyThread implements Runnable {

    private String threadName;

    protected MyThread(String threadName) {
        super();
        this.threadName = threadName;
    }

    @Override
    public void run() {
        Integer task;
        try{
            //Check in the Task pool if anything pending to process
            while( (task = getTask()) != null ){
                processTask(task);
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }finally {
            /*Reduce count when no more tasks to process. Eventually all
            Threads will end-up here, reducing the count to 0, allowing
            the flow to continue after threadsCountdown.await(); */
            threadsCountdown.countDown();
        }
    }

    private void processTask(Integer task){
        try{
            System.out.println(this.threadName+" is Working on Task: "+ task);
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }
}
}

Hope it helps!

1

You could use your own subclass of ExecutorCompletionService to wrap taskExecutor, and your own implementation of BlockingQueue to get informed when each task completes and perform whatever callback or other action you desire when the number of completed tasks reaches your desired goal.

Stephen Ostermiller
  • 18,578
  • 8
  • 74
  • 95
Alex Martelli
  • 762,786
  • 156
  • 1,160
  • 1,345
1

you should use executorService.shutdown() and executorService.awaitTermination method.

An example as follows :

public class ScheduledThreadPoolExample {

    public static void main(String[] args) throws InterruptedException {
        ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5);
        executorService.scheduleAtFixedRate(() -> System.out.println("process task."),
                0, 1, TimeUnit.SECONDS);

        TimeUnit.SECONDS.sleep(10);
        executorService.shutdown();
        executorService.awaitTermination(1, TimeUnit.DAYS);
    }

}
Rollen Holt
  • 449
  • 2
  • 10
  • 16
0

Java 8 - We can use stream API to process stream. Please see snippet below

final List<Runnable> tasks = ...; //or any other functional interface
tasks.stream().parallel().forEach(Runnable::run) // Uses default pool

//alternatively to specify parallelism 
new ForkJoinPool(15).submit(
          () -> tasks.stream().parallel().forEach(Runnable::run) 
    ).get();
Vlad
  • 9
  • 2
  • 2
    Hi Vlad, welcome to StackOverflow. Can you please edit your answer to explain how this answers the question, and what the code does? Code only answers are discouraged here. Thank you! – Tim Malone Jul 19 '16 at 23:36
  • This post talks about concurrency. Parallelism != Concurrency – GabrielBB Aug 30 '19 at 23:58
0

ExecutorService WORKER_THREAD_POOL 
  = Executors.newFixedThreadPool(10);
CountDownLatch latch = new CountDownLatch(2);
for (int i = 0; i < 2; i++) {
    WORKER_THREAD_POOL.submit(() -> {
        try {
            // doSomething();
            latch.countDown();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    });
}

// wait for the latch to be decremented by the two remaining threads
latch.await();

If doSomething() throw some other exceptions, the latch.countDown() seems will not execute, so what should I do?

0

if you use more thread ExecutionServices SEQUENTIALLY and want to wait EACH EXECUTIONSERVICE to be finished. The best way is like below;

ExecutorService executer1 = Executors.newFixedThreadPool(THREAD_SIZE1);
for (<loop>) {
   executer1.execute(new Runnable() {
            @Override
            public void run() {
                ...
            }
        });
} 
executer1.shutdown();

try{
   executer1.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);

   ExecutorService executer2 = Executors.newFixedThreadPool(THREAD_SIZE2);
   for (true) {
      executer2.execute(new Runnable() {
            @Override
            public void run() {
                 ...
            }
        });
   } 
   executer2.shutdown();
} catch (Exception e){
 ...
}
Dr. X
  • 2,446
  • 2
  • 10
  • 32
-1

This might help

Log.i(LOG_TAG, "shutting down executor...");
executor.shutdown();
while (true) {
                try {
                    Log.i(LOG_TAG, "Waiting for executor to terminate...");
                    if (executor.isTerminated())
                        break;
                    if (executor.awaitTermination(5000, TimeUnit.MILLISECONDS)) {
                        break;
                    }
                } catch (InterruptedException ignored) {}
            }
Amol Desai
  • 752
  • 1
  • 7
  • 17
-1

You could call waitTillDone() on this Runner class:

Runner runner = Runner.runner(4); // create pool with 4 threads in thread pool

while(...) {
    runner.run(new MyTask()); // here you submit your task
}


runner.waitTillDone(); // and this blocks until all tasks are finished (or failed)


runner.shutdown(); // once you done you can shutdown the runner

You can reuse this class and call waitTillDone() as many times as you want to before calling shutdown(), plus your code is extremly simple. Also you don't have to know the number of tasks upfront.

To use it just add this gradle/maven compile 'com.github.matejtymes:javafixes:1.3.1' dependency to your project.

More details can be found here:

https://github.com/MatejTymes/JavaFixes

Matej Tymes
  • 1,656
  • 1
  • 16
  • 27
-2

There is a method in executor getActiveCount() - that gives the count of active threads.

After spanning the thread, we can check if the activeCount() value is 0. Once the value is zero, it is meant that there are no active threads currently running which means task is finished:

while (true) {
    if (executor.getActiveCount() == 0) {
    //ur own piece of code
    break;
    }
}
shabeer90
  • 5,051
  • 3
  • 44
  • 64
user
  • 5
  • 1
  • 3
    Not a good idea, see http://stackoverflow.com/a/7271685/1166992 and the javadoc: "Returns the approximate number of threads that are actively executing tasks." – Olivier Faucheux Apr 24 '15 at 07:24