I'm using a task that creates other tasks. Those tasks in turn may or may not create subsequent tasks. I don't know beforehand how many tasks will be created in total. At some point, no more tasks will be created, and all the task will finish.
When the last task is done, I must do some extra stuff.
Which threading mechanism should be used? I've read about CountDownLatch, Cyclic Barrier and Phaser but none seem to fit.
I've also tried using ExecutorService, but I've encountered some issues such as the inability to execute something at the end, and you can see my attempt below:
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
public class Issue {
public static void main(String[] args) throws InterruptedException {
var count = new AtomicInteger(1);
var executor = Executors.newFixedThreadPool(3);
class Task implements Runnable {
final int id = count.getAndIncrement();
#Override
public void run() {
try {
MILLISECONDS.sleep((long)(Math.random() * 1000L + 1000L));
} catch (InterruptedException e) {
// Do nothing
}
if (id < 5) {
executor.submit(new Task());
executor.submit(new Task());
}
System.out.println(id);
}
}
executor.execute(new Task());
executor.shutdown();
// executor.awaitTermination(20, TimeUnit.SECONDS);
System.out.println("Hello");
}
}
This outputs an exception because tasks are added after shutdown() is called, but the expected output would be akin to:
1
2
3
4
5
6
7
8
9
Hello
Which threading mechanism can help me do that?
It seems pretty tricky. If there is even a single task that's either in the queue or currently executing, then since you can't say whether or not it will spawn another task, you have no way to know how long it may run for. It may be the start of a chain of tasks that takes another 2 hours.
I think all the information you'd need to achieve this is encapsulated by the executor implementations. You need to know what's running and what's in the queue.
I think you're unfortunately looking at having to write your own executor. It needn't be complicated and it doesn't have to conform to the JDK's interfaces if you don't want it to. Just something that maintains a thread pool and a queue of tasks. Add the ability to attach listeners to the executor. When the queue is empty and there are no actively executing tasks then you can notify the listeners.
Here's a quick code sketch.
class MyExecutor
{
private final AtomicLong taskId = new AtomicLong();
private final Map<Long, Runnable> idToQueuedTask = new ConcurrentHashMap<>();
private final AtomicLong runningTasks = new AtomicLong();
private final ExecutorService delegate = Executors.newFixedThreadPool(3);
public void submit(Runnable task) {
long id = taskId.incrementAndGet();
final Runnable wrapped = () -> {
taskStarted(id);
try {
task.run();
}
finally {
taskEnded();
}
};
idToQueuedTask.put(id, wrapped);
delegate.submit(wrapped);
}
private void taskStarted(long id) {
idToQueuedTask.remove(id);
runningTasks.incrementAndGet();
}
private void taskEnded() {
final long numRunning = runningTasks.decrementAndGet();
if (numRunning == 0 && idToQueuedTask.isEmpty()) {
System.out.println("Done, time to notify listeners");
}
}
public static void main(String[] args) {
MyExecutor executor = new MyExecutor();
executor.submit(() -> {
System.out.println("Parent task");
try {
Thread.sleep(1000);
}
catch (Exception e) {}
executor.submit(() -> {
System.out.println("Child task");
});
});
}
}
If you change your ExecutorService to this:
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);
You could then use the count functions to wait:
while(executor.getTaskCount() > executor.getCompletedTaskCount())
{
TimeUnit.SECONDS.sleep(10L);
}
executor.shutdown();
System.out.println("Hello");
I am creating a fixed-size thread pool with 10 threads as follows:
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < poolSize; ++i) {
executorService.execute(factory.get());
}
Now, after spawning 10 threads, a runnable is being executed by each of them. Runnable here is provided by factory.get()
Now, I wanted to do a thing that as soon as a thread gets shutdown, i.e. it has completed a task, it picks another runnable again and start running it. So, basically check for all 10 threads state and execute a runnable again if the thread is shutdown.
I know I can do something like, in which I can call the executorService shutdown() method as follows to do that:
while (!executorService.isShutdown()) {
try {
executorService.execute(factory.get());
} catch (RejectedExecutionException e) {
if (!executorService.isShutdown())
log.warn("task submission rejected");
}
}
But in this approach, issue is that I am keep on calling the execute function which would increase LinkedBlockingQueue and won't serve my purpose.
If I can somehow check the Threads state, that would be good because then, it would avoid the overhead of going back to get more work from the executor service.
Please suggest how can I do that in code.
You can use a bounded executor. The following is code by Brian Goetz from jcip
/**
* BoundedExecutor
* <p/>
* Using a Semaphore to throttle task submission
*
* #author Brian Goetz and Tim Peierls
*/
public class BoundedExecutor {
private final Executor exec;
private final Semaphore semaphore;
public BoundedExecutor(Executor exec, int bound) {
this.exec = exec;
this.semaphore = new Semaphore(bound);
}
public void submitTask(final Runnable command)
throws InterruptedException {
semaphore.acquire();
try {
exec.execute(new Runnable() {
public void run() {
try {
command.run();
} finally {
semaphore.release();
}
}
});
} catch (RejectedExecutionException e) {
semaphore.release();
}
}
}
Then just create and use it:
ExecutorService executorService = Executors.newFixedThreadPool(10);
BoundedExecutor boundedExecutor = new BoundedExecutor(executorService,10);
while (!executorService.isShutdown()) {
try {
boundedExecutor.submitTask(factory.get());
} catch (InterruptedException e) {
}
}
This way you will always have 10 threads running, new tasks will only be submitted after the old ones will complete and you can stop the execution by shutting down the executor.
Why use a thread pool if you're going to run 10 threads continually? Just start 10 threads yourself.
Why have a "controller" thread on top of the 10 worker threads? Just let each thread ask for the next task to execute.
The following assumes that factory.get() is thread-safe.
for (int i = 0; i < 10; i++) {
new Thread(() -> {
for (;;) {
Runnable r = factory.get(); // <-- must be thread-safe
if (r == null)
break; // stop thread if no more tasks to execute
try {
r.run();
} catch (Exception e) {
// log exception here
}
}
}).start();
}
If needed, save the 10 thread objects in an array.
If you want to be able to shutdown the threads without having factory.get() returning null, add a volatile boolean, and check it in the loop.
I'm learning Java threads and want my code to output threads 0-9 in sequential order. I used the synchronized keyword but I don't get the results I expect.
What should I do to correct my code?
public class MyThread extends Thread {
private static final int threadMax = 10;
private static int runCount = 0;
public void printThread() {
synchronized (this) {
while (runCount++ < 100) {
System.out.println(runCount + ": " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public void run() {
printThread();
}
public static void main(String[] args) {
for (int i = 0; i < threadMax; i++) {
new MyThread().start();
}
}
}
It is not working as every time you are creating new MyThread object and you are synchronized over that new object. So, every Thread you created will get a lock on the diffrent object. So, you should pass a common object to take the lock like below.
class MyThread extends Thread {
private static int runCount = 0;
Object lock;
public MyThread(Object lock) {
this.lock = lock;
}
public void printThread() {
synchronized (lock) {
// your code here
}
}
//.........
}
And then call it like :
Object lock = new Object();
for (int i = 0; i < threadMax; i++) {
new MyThread(lock).start();
}
However, the above program will not ensure you that it will run in sequence. There are several ways to do that. You can use wait() and notify() to achieve your goal. Refer the below example :
public void printThread() {
while (runCount < 90) {
synchronized (lock) {
while (runCount % 10 != remainder) {
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(runCount + ": " + Thread.currentThread().getName());
runCount++;
lock.notifyAll();
}
}
}
And call the thread like :
Object lock = new Object();
for (int i = 0; i < 10; i++) {
new MyThread(lock, i).start();
}
You are synchronizing the context of the thread, which is different for each one. You should put into the synchronized key any common object for all diferent threads. This won't make them run in any certain secuence, just to wait each other to end.
If you want to test the synchronized keyword for any purpose, you could pass the constructor a common variable and use it in every thread:
public class MyThread extends Thread {
private static final int threadMax = 10;
private static int runCount = 0;
private Object test; //Object pointing main method
public MyThread(Object test){
this.test = test; //This won't copy values as it is an object and not a number, string...
}
public void printThread() {
synchronized (test) { //Same object for all threads
while (runCount++ < 100) {
System.out.println(runCount + ": " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public void run() {
printThread();
}
public static void main(String[] args) {
Object test; //common object
for (int i = 0; i < threadMax; i++) {
new MyThread(test).start();
}
}
}
If you want also to make them start in order, you should "synchronize" the loop making wait and notify calls.
Anyway, the point about multithreading is to have several threads running at the "same" time and not in sequence, as that would be the same as a linear execution.
You have several tasks that you want to delegate to threads but have them executed sequentially.
As others have pointed out, wait & notify can help you achieve that : wait until Nth have finished then notify the next. However, if you wait/notify inside your printThread method, as all your threads are waiting simultaneously on the same lock, there is no guaranties that N+1th thread will be next. So you may have
1: thread-1
...
10: thread-1
11: thread-5
...
20: thread-5
21: thread-2
...
If that's ok for you, you're done. However, in a situation where you specifically want your threads to be ordered, what you need is a waiting queue (FIFO : First In First Out).
To achieve that, you can use the awesome ExecutorService. Be aware however that they hide the Threads from you and picking that solution should not be at the cost of understanding the basics of them beforehand.
An ExecutorService is a very convenient class that can receive tasks (in the form of a Runnable, see below) and will execute them in separate Threads.
Here, I'm using a SingleThreadExecutor which execute the submitted tasks sequentially. So all you have to do is call it's execute method with your tasks as arguments, and the ExecutorService will run them in the right order, one after the other.
Here's what you can do with a few notes :
public class ThreadRunner {
// Note : Constants are usually all uppercase in Java
private static final int MAX_THREADS = 10;
private final int threadName;
public ThreadRunner(int threadName) {
this.threadName = threadName;
}
public void printThread() {
// Note: For loops are better than while when you already know the number of iterations
for (int runCount = 0; runCount < 10; runCount++) {
System.out.println(runCount + "th run from thread " + threadName);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
for (int i = 0; i < MAX_THREADS; i++) {
int threadName = i + 1;
// Submit a task to the executor
executorService.execute(() -> new ThreadRunner(threadName).printThread());
}
// Nicely ask for the executor to shutdown.
// Then wait for already submitted tasks to terminate.
executorService.shutdown();
try {
executorService.awaitTermination(120, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I changed a few details, here are the reasons :
Thread creation : don't inherit from Thread
I would advise you not to inherit from Thread, but create a local instance of it, as all you need is to use a Thread ; you don't want to be a Thread :
public static void main(String[] args) {
// Using Java 1.8+ lambda
Thread lambdaThread = new Thread(() -> System.out.println("Hello from a lambda in a Thread"));
lambdaThread.start();
// Using an anonymous class for java <1.8
Thread anonClassThread = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Hello from an anonymous class in a Thread");
}
});
anonClassThread.start();
}
You're creating a new Thread passing a Runnable as constructor argument, using either lambda or anonymous class, depending of your Java version.
A Runnable is simply a portion of code that will be executed (by a Thread, in this case).
Same apply to ExecutorService, it's execute methode takes a Runnable which I've created through lambdas.
Sharing static counter between threads
Your line private static int runCount = 0; is a static field, which means it is shared by all instances of the class MyThread. When you increase it in a thread, all threads will read (and write) to the same variable.
If your threads were running sequentially, the first would do it's 100 iterations, then when the second thread starts, runCount is already at 100 and you're not entering your while loop. If that wasn't intended, it may be confusing when you'll test your code.
Based on your expected output in a comment, I believe you want your threads to do 10 iterations each, not share a pool of 100 iterations and manage somehow to have each of them only perform 10.
Having the name of the thread belong to each ThreadRunner
Small detail here : previously, you were creating 10 threads. Here, the ExecutorService only creates one that he reuse for each task you submit. So Thread.currentThread().getName() would always be thread-1.
You wouldn't be able to see which task is running without this field.
If each task is started after the previous, you don't need 10 Threads, but a single Thread performing the 10 tasks sequentially.
I've been as complete as possible, but some points might be a little bit tricky, so don't hesitate to ask for clarifications!
What is the best way to run a static method in several threads, using a thread pool?
Also I trying to pass an argument to the static method. something like
Class A{
public static runTask(int i){
....
}
}
and from a main:
ThreadPool pool = new ThreadPool(5, "poolname");
for(int i=1; i<10; i++){
A.runTask(i) // but on a new thread...
}
Thanks!
Have a look at the documentation for java.util.concurrent.Executors. It should meet your needs. Here is a simple example of using it:
public class ExecutorServiceTest {
static ExecutorService threadPool = Executors.newCachedThreadPool();
public static void main(String[] args) throws Exception {
// Queue 10 executions of someTask into the threadPool
for(int i = 0; i < 10; i++) {
runSomeTaskInThreadPool();
}
// the shutdown method causes the executor to:
// 1. stop accepting new tasks, and
// 2. allow previously queued jobs to complete, and
// 3. shut down all pooled threads once all jobs are complete
threadPool.shutdown();
// block until the threadPool has finished shutting down,
// which indicates that all tasks have finished executing
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
}
private static void runSomeTaskInThreadPool() {
Future future = threadPool.submit(new Runnable() {
public void run() {
someTask();
}
});
// TODO: Maybe keep track of futures to monitor success/failure of task
}
static AtomicInteger counter = new AtomicInteger();
public static void someTask() {
System.out.println("someTask: " + counter.incrementAndGet()
+ " on thread: " + Thread.currentThread());
}
}
Please find the detailed implementation guides:
http://java.sun.com/developer/Books/javaprogramming/threads/chap13.pdf
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.
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) {
...
}
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();
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);
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
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();
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();
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
The CyclicBarrier class in Java 5 and later is designed for this sort of thing.
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?
Follow one of below approaches.
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
Use invokeAll() on ExecutorService
CountDownLatch
ForkJoinPool or Executors.html#newWorkStealingPool
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
You could wrap your tasks in another runnable, that will send notifications:
taskExecutor.execute(new Runnable() {
public void run() {
taskStartedNotification();
new MyTask().run();
taskFinishedNotification();
}
});
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) {
...
}
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();
}
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());
}
}
}
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();
}
}
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");
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.
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!
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.
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);
}
}
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){
...
}
Try-with-Resources syntax on AutoCloseable executor service with Project Loom
Project Loom seeks to add new features to the concurrency abilities in Java.
One of those features is making the ExecutorService AutoCloseable. This means every ExecutorService implementation will offer a close method. And it means we can use try-with-resources syntax to automatically close an ExecutorService object.
The ExecutorService#close method blocks until all submitted tasks are completed. Using close takes the place of calling shutdown & awaitTermination.
Being AutoCloseable contributes to Project Loom’s attempt to bring “structured concurrency” to Java.
try (
ExecutorService executorService = Executors.… ;
) {
// Submit your `Runnable`/`Callable` tasks to the executor service.
…
}
// At this point, flow-of-control blocks until all submitted tasks are done/canceled/failed.
// After this point, the executor service will have been automatically shutdown, wia `close` method called by try-with-resources syntax.
For more information on Project Loom, search for talks and interviews given by Ron Pressler and others on the Project Loom team. Focus on the more recent, as Project Loom has evolved.
Experimental builds of Project Loom technology are available now, based on early-access Java 18.
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();
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?
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) {}
}
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
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;
}
}