I have a group of threads which all need to be executed in parallel and I must wait on all of them to complete.
Should I use the plain old Thread or the ExecutorService ? for the ExecutorService.awaitTermination I must give a certain time that I'm willing to wait but for Thread.join I must not.
I don't do anything with the results that the threads give , I don't need any futures.
EDIT:
ExecutorService es = Executors.newFixedThreadPool(kThreads);
List<Callable<Void>> calls = new LinkedList<>();
container.forEach(
calls.add(() -> { //creating a thread/task
BufferedImage scaledBufferedImage=imageService.scale(...);
imageService.transferToAWS(...);
return null;
})
);
es.invokeAll(calls); //executes each task
es.shutdown(); //ensure that no new tasks will be accepted
es.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); //wait for all tasks to finish
return kLinksToTheScaledImages;
As you say, you don't need the Futures as such, but you can use them to await termination.
Since you're using Java 8, you can do this via
ExecutorService es = Executors.newFixedThreadPool(kThreads);
container.stream()
.map(d -> createRunnable(d)) // now you have Runnables
.map(es::submit) // now they're Futures
.forEach(Future::get); // get() will wait for futures to finish
EDIT:
I just realized that the stream will probably prevent the parallelism to begin with, so you need to collect them intermediately:
List<Future<?>> futures = container.stream()
.map(d -> createRunnable(d)) // now you have Runnables
.map(es::submit) // now they're Futures
.collect(Collectors.toList());
futures.forEach(Future::get);
Actually, I fully understand that people are confused about having to wait without the futures returning a value. IMO, it would make more sense to have each future return the link of the upload it creates:
String scaleAndUpload() {
BufferedImage scaledBufferedImage=imageService.scale(...);
imageService.transferToAWS(...);
return linkToUploadedImage;
}
So you would get something like
List<Future<?>> futures = container.stream()
.map(d -> scaleAndUpload()) // now you have Runnables
.map(es::submit) // now they're Futures
.collect(Collectors.toList());
return futures.stream()
.map(Future::get) // collect the link when the future is finished
.collect(Collectors.toList()); // create a list of them
go for the executor service. this gives you many other benefits on top of managing the thread termination (e.g. capacity scaling and separation of execution logic and the actual tasks)
With Executors you just do this.
ex.shutdown();
while (!ex.awaitTermination(1, TimeUnit.MINUTES)) {
}
Where ex is your ExecutorService. In the loop you can check if your threads are still alive or something like that.
Should I use the plain old Thread or the ExecutorService ?
Use ExecutorService
for the ExecutorService.awaitTermination I must give a certain time that I'm willing to wait but for Thread.join I must not.
You have to look into this post for proper shutdown of ExecutorService.
How to properly shutdown java ExecutorService
Few more alternatives have been quoted in this post:
wait until all threads finish their work in java
You can do while(!executor.isTerminated) {}. Then you don't have to say how long you are willing to wait.
Related
I have a list of futures over which i keep looping checking Future.isDone() and if yes, then i use Future.get(). But, there are cases where the thread goes on forever and to avoid this i want to timeout.
Please help me timing out a future without using Future.get() as its a blocking operation. Most of the questions on timing out here on stackoverflow point to Future.get() with a timeout inside it.
If you can use CompletableFuture instead of plain Future you can use CompletableFuture.anyOf() method:
Returns a new CompletableFuture that is completed when any of the given CompletableFutures complete, with the same result.
CompletableFuture<Void> combinedFuture =
CompletableFuture.anyOf(future1, future2, future3);
combinedFuture.get();
if (future1.isDone()) { ... }
if (future2.isDone()) { ... }
if (future3.isDone()) { ... }
In Java 9 you have extra methods for handling timeouts e.g. CompletableFuture.completeOnTimeout().
I am having confusion with defining executor in CompletableFuture. I am not sure how to tell CompletableFuture to run it in that particular executor. Thanks in advance.
//Suppose I have an executor
ExecutorService myExecutor=Executors.newFixedThreadPool(2);
//If I create a future like this
CompletableFuture.runAsync(() -> {
//Do something
}, myExecutor); // I can put the executor here and say the future to this executor
//But I do not know where to put executor if I create my future in method style like this
private final CompletableFuture<Void> myMethod(String something) {
//Do something
return null;
}
//and use it like this
.thenCompose(this::myMethod); //How can I specify the executor in this case?
In your example, you have 3 CompletableFutures that are at play:
the one returned by runAsync()
the one returned by myMethod()
the one returned by thenCompose()
You also have 4 tasks that need to be run:
the one passed to runAsync() will be executed on the given executor and handle future 1;
the one that calls myMethod() from thenCompose() to create future 2 can be run on any executor, use thenComposeAsync() to explicitly choose one;
the one that will complete future 2 returned by myMethod() – this will be controlled inside myMethod() itself;
the one that will complete future 3 returned by thenCompose() – this is handled internally and will depend on execution order (e.g. if myMethod() returns an already completed future, it will also complete the former).
As you can see, several tasks and executors are involved, but you can always control the executors used in dependent stages using *Async() variants. The only case where you don't really control it is the 4th case, but it is a cheap operation as long as dependent stages use the *Async() variants as well.
you can do something like this:
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();
I have an ExecutorService containing a number of running Callables. I have a list of Futures for these Callables. I want to find out as soon as possible if one of the Callables throws an Exception. All Callables are equally likely to throw an Exception. The Callables usually run for several hours.
The usual approach seems to be to use the Future.get() method. However, you can only use this for one Future. If another Future throws an Exception I am not notified. So I was thinking of writing a loop that checks the Future.isDone() method for all Futures and sleeping for some time after each iteration. However, this approach is not really nice, so I was wondering if there is a better way of doing this?
You should use an ExecutorCompletionService, wrap your executor with it and then calling #take() will return the first completed result.
Example:
CompletionService<Object> completionService = new ExecutorCompletionService<>(executor);
//submit a bunch of tasks
IntStream.range(0, 100).forEach(i-> completionService.submit(Object::new));
//Wait for any of them to complete, wrap in a loop to take them all
completionService.take();
You can use CompletableFuture for your use-case
static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs)
Returns a new CompletableFuture that is completed when any of the
given CompletableFutures complete, with the same result. Otherwise, if
it completed exceptionally, the returned CompletableFuture also does
so, with a CompletionException holding this exception as its cause.
If no CompletableFutures are provided, returns an incomplete
CompletableFuture.
You should store all your futures in a list. `
Now
List<CompletableFuture<?>> futureList = // all futures;
while(futureList.size()>0){
CompletableFuture<?> completed = CompletableFuture.anyOf(futureList); //convert futureList to array
if(completed.isCompletedExceptionally()){
// first future that completed with an exception
}else{
//future completed without exception, store the result or process
futureList.remove(completed); // remove it from the incomplete list
}
}
You may obtain a CompletableFuture like
final CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
//...long running...
return "returnVal";
},
executor); //here executor is your executor pool
If you don't want to use explicit executor pool
final CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
//...long running...
return "returnVal";
});
However, in this case it will be submitted to the ForkJoinPool.commonPool()
Imagine that we have the following dummy code:
CompletableFuture<BigInteger> cf1 = CompletableFuture.supplyAsync(() -> BigInteger.valueOf(2L));
CompletableFuture<BigInteger> cf2 = CompletableFuture.supplyAsync(() -> BigInteger.valueOf(3L));
cf1.thenCombine(cf2, (x, y) -> x.add(y)).thenAccept(System.out::println);
Does JVM know that cf1 and cf2 carry independent threads in this case? And what will change if threads will be dependent (for example, use one connection to database)?
More general, how does CompletableFuture synchronize threads?
A CompletableFuture has no relation to any thread. It is just a holder for a result retrieved asynchronously with methods to operate on that result.
The static supplyAsync and runAsync methods are just helper methods. The javadoc of supplyAsync states
Returns a new CompletableFuture that is asynchronously completed by a
task running in the ForkJoinPool.commonPool() with the value obtained
by calling the given Supplier.
This is more or less equivalent to
Supplier<R> sup = ...;
CompletableFuture<R> future = new CompletableFuture<R>();
ForkJoinPool.commonPool().submit(() -> {
try {
R result = sup.get();
future.complete(result);
} catch (Throwable e) {
future.completeExceptionally(e);
}
});
return future;
The CompletableFuture is returned, even allowing you to complete it before the task submitted to the pool.
More general, how does CompletableFuture synchronize threads?
It doesn't, since it doesn't know which threads are operating on it. This is further hinted at in the javadoc
Since (unlike FutureTask) this class has no direct control over the
computation that causes it to be completed, cancellation is treated as
just another form of exceptional completion. Method cancel has the
same effect as completeExceptionally(new CancellationException()).
Method isCompletedExceptionally() can be used to determine if a
CompletableFuture completed in any exceptional fashion.
CompletableFuture objects do not control processing.
I don't think that a CompletableFuture (CF) "synchronizes threads". It uses the executor you have provided or the common pool if you have not provided one.
When you call supplyAsync, the CF submits the various tasks to that pool which in turns manages the underlying threads to execute the tasks.
It doesn't know, nor does it try to synchronize anything. It is still the client's responsibility to properly synchronize access to mutable shared data.
Is there a way to wait on an AtomicInteger so that I don't have to keep sleeping my current thread and keep checking on the AtomicInteger like this
while(atomicInt.get() >= 0) {
Thread.sleep(1000)
}
I know there is such a thing as a CountDownLatch but that only allows me to decrement I also need it to be able to increment
Further BackStory -
I have a loop creating threads and I need to wait on one of the threads execution to finish before creating a new thread. I however am using an Executors.newFixedThreadPool(numThreads) and the only way to wait on it seems to be to call the shutdown method await termination and then create a new threadPool so instead I was using an atomic integer to keep track of how many threads were running and/or on the queue so that when that number decreased I could continue with the loop.
Semaphore looks like it might be closer to what you're looking for, actually -- it lets you wait until one or more "permits" is available. AtomicInteger isn't meant to be used how you're using it.
I think what you really want is to process some event. That event could in turn increment an integer. Take a peek at the BlockingQueue.
A Queue that additionally supports operations that wait for the queue to become non-empty when retrieving an element, and wait for space to become available in the queue when storing an element.
The code could look something like...
MyEvent incrementEvent = queue.take(); //blocks until an event is added to the queue
// increment int and do logic here
I think a closer match to what you want is a Phaser. My rough understanding is that its a bit like an incrementing counter where you can block until the number is incremented.
// This constructor one party (so it expects one advance per phase).
Phaser phaser = new Phaser(1);
try {
// This will timeout as phase 0 hasn't arrived yet.
phaser.awaitAdvanceInterruptibly(0, 1, TimeUnit.MILLISECONDS);
fail();
}
catch (TimeoutException expected) {
}
// Arrive phase 0
phaser.arrive();
phaser.awaitAdvance(0);
try {
// Phase 1 will timeout..
phaser.awaitAdvanceInterruptibly(1, 1, TimeUnit.MILLISECONDS);
fail();
}
catch (TimeoutException expected) {
}
// Arrive phase 1
phaser.arrive();
phaser.awaitAdvance(0);
phaser.awaitAdvance(1);
If you are using Executors API, the right way to wait for task complete is using the Future API. Sample code is show below:
Future<?> future = threadPool.submit(task);
future.get();
Simple solution with CompletableFuture
Create CompletableFuture accessible by both threads thread1, thread2
private CompletableFuture<Integer> future = new CompletableFuture<>();
Wait for value in thread1 (or multiple threads)
Integer value = future.join();
Calculate value in thread2 and complete future
if (!future.isDone()) future.complete(calculatedValue);