Retrieving result from List List<Future<Callable<Integer>>> - java

Task:
You are given a List of Future objects that return Callable. You should execute these Callable objects in the reverse order, starting from the end of the List and return a sum of values returned by these Callable objects.
Method to implement:
import java.util.concurrent.*;
class FutureUtils {
public static int executeCallableObjects(List<Future<Callable<Integer>>> items) {
// write your code here
}
}
so, the question is how to retrieve the results of Callable tasks correctly
What I understand:
1) In order to submit Callable we need to use
ExecutorService exec = Executors.newFixedThreadPool(4);
exec.submit(put Callable);
2) In order to retrieve result of Callable execution, we need to use Future object;
I understand how to retrieve results from the Callable list but not from >>
I believe I miss something.
This is the code I wrote trying to understand how to complete the task
public static void main(String[] args) throws InterruptedException, IOException {
ExecutorService executorService = Executors.newFixedThreadPool(4);
List<Future<Callable<Integer>>> list = new ArrayList<>();
Future first = executorService.submit(new PrintIfPrimeTask(1));
list.add(first);
try {
ExecutorService exec = Executors.newFixedThreadPool(4);
Future<Callable<Integer>> good = list.get(0);
Callable<Integer> temp = good.get();
Future<Integer> kek = exec.submit(temp);
Integer a = (Integer) kek.get();
System.out.println(a);
} catch (Throwable e) {
e.printStackTrace();
}
executorService.shutdown();
}
}
It gives
java.lang.ClassCastException: java.base/java.lang.Integer cannot be cast to java.base/java.util.concurrent.Callable
at Solution.main(Solution.java:36)
PrintIfPrimeTask does nothing but return 2
class PrintIfPrimeTask implements Callable<Integer> {
private final int number;
public PrintIfPrimeTask(int number){
this.number = number;
}
#Override
public Integer call() throws Exception {
return 2;
}
}

Related

How to return value from Callable with CountDownLatch?

I want to use CountDownLatch with Callabe interface. I have Person class implements Callable interface which has CountDownLatch and Integer, Person#call() method returns integer value and within finally block countDown() method called. 2 Threads created by Executors.newFixedThreadPool(2) and submitted Person objects within Main class.I want to know this implementation is ok?
public class Person implements Callable<Integer> {
private final CountDownLatch countDownLatch;
private final Integer count;
public Person(CountDownLatch countDownLatch, Integer count) {
this.countDownLatch = countDownLatch;
this.count = count;
}
#Override
public Integer call() throws Exception {
try {
return count;
} finally {
countDownLatch.countDown();
}
}
}
public class Main {
public static void main(String[] args) throws InterruptedException, ExecutionException {
CountDownLatch countDownLatch = new CountDownLatch(2);
ExecutorService executorService = Executors.newFixedThreadPool(2);
Future<Integer> future1 = executorService.submit(new Person(countDownLatch, 5));
Future<Integer> future2 = executorService.submit(new Person(countDownLatch, 4));
countDownLatch.await();
executorService.shutdown();
System.out.println(future1.get() + future2.get());
}
}
I want to know this implementation is ok?
That totally depends on what you are trying to achieve with this code.
As is, your code is simply adding 5 and 4 together and printing the result of 9 to the console. You could simply do that with:
System.out.println(5+4);
If the point of your code is to use a CountDownLatch effectively, then yes you are using it correctly to detect that the Call() method has been invoked on both Person objects in an asynchronous manner before continuing the main method/thread.

Java 8 mulithreading: How can I achieve parallelism along with a timeout for individual threads?

Summary of what I want to achieve:
I want to execute N tasks in parallel such that no individual task should run for more than two seconds (we can mark such tasks as failed). As an output I want to return the output of successful tasks and status of failed tasks as failed. Also a timeout of one task should not lead to a circuit break, i.e., other tasks execution should not stop.
Note: I am restricted to use Java 8.
I referenced this article for parallel processing. I am doing a similar kind of parallel processing as given in the example in this article:
public void parallelProcessing() {
try {
ExecutorService executorService = Executors.newWorkStealingPool(10);
List<CompletableFuture<Integer>> futuresList = new ArrayList<CompletableFuture<Integer>>();
futuresList.add(CompletableFuture.supplyAsync(()->(addFun1(10, 5)), executorService));
futuresList.add(CompletableFuture.supplyAsync(()->(subFun1(10, 5)), executorService));
futuresList.add(CompletableFuture.supplyAsync(()->(mulFun1(10, 5)), executorService));
CompletableFuture<Void> allFutures = CompletableFuture.allOf(futuresList.toArray(new CompletableFuture[futuresList.size()]));
CompletableFuture<List<Integer>> allCompletableFuture = allFutures.thenApply(future -> futuresList.stream().map(completableFuture -> completableFuture.join())
.collect(Collectors.toList()));
CompletableFuture<List<Integer>> completableFuture = allCompletableFuture.toCompletableFuture();
List<Integer> finalList = (List<Integer>) completableFuture.get();
} catch (Exception ex) {
}
}
public static Integer addFun1(int a, int b) {
System.out.println(Thread.currentThread().getName());
for (int i = 0; i < 10; i++) {
System.out.print(Thread.currentThread().getName() + i);
}
return a + b;
}
public static Integer subFun1(int a, int b) {
System.out.println(Thread.currentThread().getName());
for (int i = 0; i < 10; i++) {
System.out.print(Thread.currentThread().getName() + i);
}
return a - b;
}
public static Integer mulFun1(int a, int b) {
System.out.println(Thread.currentThread().getName());
for (int i = 0; i < 10; i++) {
System.out.print(Thread.currentThread().getName() + i);
}
return a * b;
}
This works fine. But I want to set a timeout for an individual thread. I know I can use an overloaded get function in the last line. But that would set the timeout for combined futures, right? E.g., if I want no individual thread should be blocked for more than 2 seconds, and if I set a 2 seconds timeout in the last line, it will be combined timeout, right?
get(long timeout, TimeUnit unit)
Here's what I want to achieve as a final outcome:
Suppose there are five threads and four complete on time, one timeout (due to running more than two seconds). In this case, I want to send the output of four threads and send the error for the fifth thread in the result.
My input/output format is in the following way:
Sample input: List<Input> each item is run in a separate thread, where each input has a uniqueIdentifier.
Sample output: List<Output> such that:
Output :{
uniqueIdentifier: // Same as input to map for which input this output was generated
result: success/fail // This Field I want to add. Currently it's not there
data: {
// From output, e.g., addFun1 and subFun1
}
}
The semantics of what you want to achieve matter very much. On one hand, you say that you want an alternative for orTimeout for Java 8; on the other hand you kind of imply that you want to drop execution of a certain CompletableFuture if it goes beyond a certain threshold.
These are very different things, because orTimeout says in the documentation:
Exceptionally completes this CompletableFuture with a TimeoutException if not otherwise completed before the given timeout.
So something like:
CompletableFuture<Integer> addAsy =
supplyAsync(() -> addFun1(10,5), executorService)
.orTimeout(5, TimeUnit.MILLISECONDS);
will result in a CompletableFuture that is completed exceptionally (assuming that addFun1 takes more than 5 ms). At the same time, this:
CompletableFuture<Void> allFutures = CompletableFuture
.allOf(futuresList.toArray(new CompletableFuture[0]));
as the documentation states in the allOf:
... If any of the given CompletableFutures complete exceptionally, then the returned CompletableFuture also does so...
means that allFutures is a CompletableFuture that is completed exceptionally too (because addAsy is).
Now, because you have this:
CompletableFuture<List<Integer>> allCompletableFuture = allFutures.thenApply(future -> {
return futuresList.stream().map(CompletableFuture::join)
.collect(Collectors.toList());
});
And again, the documentation of thenApply says:
Returns a new CompletionStage that, when this stage completes normally, is executed with this stage's result as the argument to the supplied function.
Your allFutures did not complete normally, as such this is not even called.
So you need to understand what exactly you want to achieve. For a backport of orTimeout you could start by looking here.
You still need some kind of a backport for orTimeout. I will use the method as if it already exists.
static void parallelProcessing() throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(10);
List<CompletableFuture<Integer>> futuresList = new ArrayList<>();
futuresList.add(CompletableFuture.supplyAsync(() -> addFun1(10,5), executorService).orTimeout(2, TimeUnit.SECONDS));
futuresList.add(CompletableFuture.supplyAsync(() -> subFun1(10,5), executorService));
futuresList.add(CompletableFuture.supplyAsync(() -> mulFun1(10,5), executorService));
CompletableFuture<Void> all = CompletableFuture.allOf(futuresList.toArray(new CompletableFuture[0]));
Map<Boolean, List<CompletableFuture<Integer>>> map =
all.thenApply(x -> both(futuresList)).exceptionally(x -> both(futuresList)).get();
List<CompletableFuture<Integer>> failed = map.get(Boolean.TRUE);
List<CompletableFuture<Integer>> ok = map.get(Boolean.FALSE);
System.out.println("failed = " + failed.size());
System.out.println("ok = " + ok.size());
}
private static Map<Boolean, List<CompletableFuture<Integer>>> both(
List<CompletableFuture<Integer>> futuresList) {
return futuresList.stream().collect(Collectors.partitioningBy(
CompletableFuture::isCompletedExceptionally
));
}
The following is a single-file mre (paste the entire code into RunParallelTasks.java and run). It is a prototype of the structure I suggested in my comment aimed to achieve the required functionality by using simple means:
import java.util.Optional;
public class RunParallelTasks {
public static void main(String[] args) {
new Thread(()->{
long duration = 3000;
Callback<Long> cb = new LongTask(duration);
Output<Long> output = new TaskExecuter<Long>().work(cb);
System.out.println( output);
}).start();
new Thread(()->{
long duration = 300;
Callback<Long> cb = new LongTask(duration);
Output<Long> output = new TaskExecuter<Long>().work(cb);
System.out.println( output);
}).start();
new Thread(()->{
long duration = 4000;
Callback<Long> cb = new LongTask(duration);
Output<Long> output = new TaskExecuter<Long>().work(cb);
System.out.println( output);
}).start();
new Thread(()->{
long duration = 1000;
Callback<Long> cb = new LongTask(duration);
Output<Long> output = new TaskExecuter<Long>().work(cb);
System.out.println( output);
}).start();
}
}
class TaskExecuter<T>{
private static final long TIMEOUT = 2000;//millis
private T value = null;
public Output<T> work(Callback<T> call){
Thread t = new Thread(()->{
value = call.work();
});
t.start();
try {
t.join(TIMEOUT);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
return new Output<>(t.getId(), value == null ? Optional.empty() : Optional.of(value)) ;
}
}
interface Callback<T> {
T work();
}
class LongTask implements Callback<Long>{
private final long durationInMillis;
public LongTask(long durationInMillis) {
this.durationInMillis = durationInMillis;
}
#Override
public Long work() {
try {
Thread.sleep(durationInMillis);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
return durationInMillis;
}
}
class Output<T> {
private final long id;
private boolean success = false;
private T data;
public Output(long id, Optional<T> op) {
this.id = id;
if(!op.isEmpty()) {
data = op.get();
success = true;
}
}
//todo add getters
#Override
public String toString() {
return "task "+ id+ (success ? " Completed, returned "+data : " Failed" );
}
}
I believe that in order to achieve canceling a task if execution takes too long, you need two tasks:
The task itself doing the computation
Another task, which takes care to cancel the first, if it takes too long
This is inspired by my answer here, at least for now i still have not come up with a better way to do it.
Let's say this is Output:
public class Output {
private final String uniqueIdentifier;
private final boolean result;
private final Object data;
//all arguments constructor and getters
#Override
public String toString() {
return "Output{" +
"uniqueIdentifier='" + uniqueIdentifier + '\'' +
", result=" + result +
", data=" + data +
'}';
}
}
For simplicity i'll use only add integers task from your example, wrapping it in a Supplier.
public class AddIntegerTask implements Supplier<Integer> {
private static final long NANOSECONDS_IN_SECOND = 1_000_000_000;
private final String uniqueIdentifier;
private final boolean tooLong;
private final int a;
private final int b;
public AddIntegerTask(boolean tooLong, int a, int b) {
this.uniqueIdentifier = UUID.randomUUID().toString();
this.tooLong = tooLong;
this.a = a;
this.b = b;
}
#Override
public Integer get() {
long nanoseconds = this.tooLong ? 3 * NANOSECONDS_IN_SECOND : NANOSECONDS_IN_SECOND;
long start = System.nanoTime();
long toEnd = start + nanoseconds;
//simulate long execution
while (System.nanoTime() <= toEnd) {
//check for interruption at crucial points
boolean interrupted = Thread.currentThread().isInterrupted();
if (interrupted) {
//custom exception extending RuntimeException
throw new TooLongExecutionException();
}
}
return this.a + this.b;
}
public String getUniqueIdentifier() {
return this.uniqueIdentifier;
}
}
Most important here is, that you need to check the current thread for interruption at key moments in your own implementation.
The cancel task is quite straightforward:
public class CancelTask implements Runnable {
private final Future<?> future;
public CancelTask(Future<?> future) {
this.future = future;
}
#Override
public void run() {
this.future.cancel(true);
}
}
Wrap the canceling of a Future in a Runnable, so it can be scheduled for execution with approproate delay.
And the Runnable, which will wrap the result in an Output, and will be submitted for execution:
public class MyRunnable implements Runnable {
private final Map<String, Output> outputMap;
private final AddIntegerTask calcFunction;
private final CountDownLatch latch;
public MyRunnable(Map<String, Output> outputMap, AddIntegerTask calcFunction, CountDownLatch latch) {
this.outputMap = outputMap;
this.calcFunction = calcFunction;
this.latch = latch;
}
#Override
public void run() {
String uniqueIdentifier = this.calcFunction.getUniqueIdentifier();
Output output;
try {
Integer result = this.calcFunction.get();
output = new Output(uniqueIdentifier, true, result);
} catch (TooLongExecutionException exc) {
output = new Output(uniqueIdentifier, false, null);
}
this.outputMap.replace(uniqueIdentifier, output);
this.latch.countDown();
}
}
Things to note here: CountDownLatch, it looks to me that you know the number of tasks beforehand, so it's a good choice to force main thread to wait until all tasks have finished. TooLongExecutionException is a custom exception extending RuntimeException. If the job completes, set as successful with result, if it was interrupted set to not successful without result.
And a main to combine and test all that:
public class CancelingMain {
public static void main(String[] args) throws InterruptedException {
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(10);
int taskCount = 6;
CountDownLatch latch = new CountDownLatch(taskCount);
long start = System.nanoTime();
Map<String, Output> outputMap = new LinkedHashMap<>();
for (int i = 1; i <= taskCount; i++) {
boolean tooLong = i % 2 == 0;
AddIntegerTask task = new AddIntegerTask(tooLong, 10, 7);
outputMap.put(task.getUniqueIdentifier(), null);
MyRunnable runnable = new MyRunnable(outputMap, task, latch);
Future<?> future = executorService.submit(runnable);
//schedule cancel task to run once, 2 seconds after scheduling
executorService.schedule(new CancelTask(future), 2, TimeUnit.SECONDS);
}
latch.await();
System.out.println("execution took - " + (System.nanoTime() - start) / 1_000_000_000D);
executorService.shutdown();
outputMap.values().forEach(System.out::println);
}
}
I am using LinkedHashMap in order to keep the tasks in their order of submission.
Here's a fleshed out version of what I suggested in a comment to the question. The idea is to wrap a call to get(long timeout, TimeUnit unit) into another future. I encapsulate the required logic into a BetterFuture class, which delegates to a CompletableFuture under the hood:
import static java.util.concurrent.CompletableFuture.completedFuture;
import static java.util.concurrent.CompletableFuture.runAsync;
import static java.util.stream.Stream.concat;
import java.time.Duration;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Function;
import java.util.stream.Stream;
public class BetterFuture<T> {
private final CompletableFuture<T> delegate;
private BetterFuture(CompletableFuture<T> delegate) {
this.delegate = delegate;
}
public static <T> BetterFuture<T> completed(T value) {
return new BetterFuture<>(completedFuture(value));
}
public static <T> BetterFuture<T> future(Executor executor, Callable<T> callable) {
CompletableFuture<T> delegate = new CompletableFuture<T>();
runAsync(() -> {
try {
delegate.complete(callable.call());
} catch (Throwable e) {
delegate.completeExceptionally(e);
}
}, executor);
return new BetterFuture<>(delegate);
}
public static <T> BetterFuture<Optional<T>> future(Executor executor, Callable<T> callable, Duration timeout) {
return future(executor, () -> future(executor, callable).get(timeout));
}
public <R> BetterFuture<R> map(Function<T, R> fn) {
return new BetterFuture<>(delegate.thenApply(fn));
}
public <R> BetterFuture<R> andThen(Function<T, BetterFuture<R>> fn) {
return new BetterFuture<>(
delegate.thenCompose(value -> fn.apply(value).delegate));
}
public static <T> BetterFuture<Stream<T>> collect(Stream<BetterFuture<T>> futures) {
return futures
.map(future -> future.map(Stream::of))
.reduce(
BetterFuture.completed(Stream.empty()),
(future1, future2) ->
future1
.andThen(stream1 ->
future2
.map(stream2 ->
concat(stream1, stream2)))
);
}
public T get() throws ExecutionException, InterruptedException {
return delegate.get();
}
public Optional<T> get(Duration timeout) throws ExecutionException, InterruptedException {
try {
return Optional.of(delegate.get(timeout.toMillis(), TimeUnit.MILLISECONDS));
} catch (TimeoutException e) {
return Optional.empty();
}
}
}
Most of the methods just delegate to the underlying CompletableFuture without adding much additional functionality.
To start an async task with a timeout, use the method
<T> BetterFuture<Optional<T>> future(Executor executor, Callable<T> callable, Duration timeout)
If a timeout occurs, it completes with empty and with an optional of T otherwise.
In addition the method
public static <T> BetterFuture<Stream<T>> collect(Stream<BetterFuture<T>> futures)
provides a convenient way for collecting a stream of futures into a future of a stream of the same type:
Stream<BetterFuture<Optional<String>>> futures = ...
BetterFuture<Stream<Optional<String>>> futureStream = BetterFuture.collect(futures);
Here's a full fledged examples where the first future times out and the second one completes successfully:
#Test
public void timeoutTest() throws ExecutionException, InterruptedException {
ExecutorService executor = Executors.newCachedThreadPool();
BetterFuture<Optional<String>> fa = BetterFuture.future(executor, () -> {
Thread.sleep(3000);
return "a";
}, Duration.ofSeconds(2));
BetterFuture<Optional<String>> fb = BetterFuture.future(executor, () -> {
Thread.sleep(1000);
return "b";
}, Duration.ofSeconds(2));
Stream<BetterFuture<Optional<String>>> futures = Stream.of(fa, fb);
BetterFuture<Stream<Optional<String>>> c = BetterFuture.collect(futures);
System.out.println(c.get().toList());
}
When run, it prints
[Optional.empty, Optional[b]]
As a final note, the implementation does nothing about the running threads when a timeout occurs. That is, it only times out the future but it does not interrupt the running thread. The thread will keep running in the background until in completes naturally.
It totally depends on the tasks / calculations you are running in parallel if you can really cancel them. Keep in mind that the Java Runtime is not an operating system, and you cannot forcible kill a thread like you could do with a process.
So if you want to interrupt long-running calculations, you will have to write time in a way so they regularly check if they should stop execution. For waiting on some other stuff (sleep, sync on other threads etc.) it is a totally different strategy: you can interrupt such threads and the code receives a InterruptedException that can be used to really stop the code with much less cooperation from the code.
I prepared a small example here to show you the difference:
package examples.stackoverflow.q71322315;
import java.util.concurrent.*;
public class Q71322315 {
public static final long COUNTER = 10000000000L;
public static final boolean SLEEP = false;
private static final ExecutorService taskExec = Executors.newCachedThreadPool();
public static void timedRun(Runnable r, long timeout, TimeUnit unit) throws InterruptedException {
Future<?> task = taskExec.submit(r);
try {
task.get(timeout, unit);
System.out.println("completed");
} catch (TimeoutException e) {
// task will be cancelled below
System.out.println("timeout");
} catch (ExecutionException e) {
System.out.println("exex");
// exception thrown in task; rethrow
throw new RuntimeException(e.getCause());
} finally {
// Harmless if task already completed
task.cancel(true); // interrupt if running
}
}
public static void main(String[] args) throws InterruptedException {
timedRun(new Task(SLEEP), 2000, TimeUnit.MILLISECONDS);
taskExec.shutdown();
System.out.println("finish");
}
private static class Task implements Runnable {
private final boolean sleep;
private Task(boolean sleep) {
this.sleep = sleep;
}
#Override
public void run() {
try {
if (sleep) {
Thread.sleep(5000L);
} else {
longRunningMethod(COUNTER);
}
System.out.println("Success");
} catch (Exception e) {
e.printStackTrace();
if (e instanceof InterruptedException) {
Thread.currentThread().interrupt();
}
}
}
private void longRunningMethod(long counter) {
for (long y = 0; y < counter; y++) {
Math.sqrt(y);
}
}
}
}
The example is based on some example code of the already mentioned Java Concurrency in Practice - "7.10 Cancelling a task using Future."
The code as above performs a long running calculation that doesn't care about any interruptions. (You might have to increase the value of COUNTER, just add zeros at the end until the whole method takes longer than 2 seconds.)
You will see that you first get the "timeout" message that indicates that the task wasn't finished in the wanted timeout. But the code continues running and also prints out "finish" and "Success".
When you flip the SLEEP constant to true it uses an interruptible call to Thread.sleep() instead and the output will not contain the "Success" message.
After you managed to build a cancellable / interruptible computation you can then set up multiple threads that each execute the timedRun execution in parallel, so the tasks are started in parallel and also interrupted after the timeout.
This does not yet include the collection of the results, but instead of the sysouts for completed and timeout you can collect results or count the timed out tasks.
(And if you want to use that code in production, please clean it up very thoroughly, it has really some huge smells that should never land in any production ready code ;-)
We had similar requirement where we need capture timeout of each thread and ignore the results. Java 8 doesn't have this in built.
One of the ways we achieved it,
List<CompletableFuture<?>> futures = new ArrayList<>();
List<?> results = new ArrayList<>(); // It can be anything you collect
futures.add(asyncService.fetchMethod()
.acceptEither(
timeoutAfter(timeout, TimeUnit.SECONDS),
results:add)
.handle(
(result, ex) -> {
//Handle the timeout exception
results.add(...);
return result
});
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
private <T> CompletableFuture<T> timeoutAfter(long timeout, TimeUnit unit) {
CompletableFuture<T> result = new CompletableFuture<>();
// We need a separate executor here
scheduledExecutor.schedule(
() -> result.completeExceptionally(new TimeoutException()), timeout, unit);
);
return result;
}
Suppose you want 10 threads running and want a returned value, you can use the Callable<Boolean> interface, submit it to ExecutorService, and then get the result using Future#get returned as a Boolean.
Here is an example usage.
final int NUM_THREADS = 10;
List<Boolean> results = new ArrayList<Boolean>();
List<Callable<Boolean>> callables = new ArrayList<Callable<Boolean>>();
for(int i=0; i<NUM_THREADS; ++i)
{
callables.add(new Callable<Boolean>()
{
public Boolean call()
{
// Add your task here
return isTaskCompleted;
}
});
}
ExecutorService executorService = ExecutorService.newFixedThreadPool(NUM_THREADS); // Run 10 threads
for(Callable<Boolean> callable:callables)
{
Future<Boolean> future = executor.submit(callable);
try
{
results.add(future.get(2, TimeUnit.SECONDS)); // Timeout 2 seconds and add the result
}
catch(Exception ex)
{
results.add(false); // Set result to false if task throw TimeOutExeption
}
}
If you want more information about these classes you can read this book: O'Reilly - Learning Java, Chapter 9: Threads.
Here is what helped me.
Problem in hand: Given X seconds as timeout return the value from the Task which completes first, in case none of the Task is able to finish then return default value.
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class Test {
public static void main(String[] args) {
CompletableFuture<String> f1 = CompletableFuture.supplyAsync(() -> func("Task 1", 1000));
CompletableFuture<String> f2 = CompletableFuture.supplyAsync(() -> func("Task 2", 2000));
String str = null;
try {
str = (String) CompletableFuture.anyOf(f1, f2).get(3, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
str = "Default";
e.printStackTrace();
}
System.out.println(str);
}
public static String func(String task, int sleepTime) {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
return task;
}
}

Getting results back to the caller from worker threads

There are some answers on SO but I'm looking for a solution using my code for clear understanding.
I've created worker threads using Executor, and after performing work, the workers are to return results back to the caller (main)
Worker
public class Worker implements Runnable {
private final int num;
public Worker(int num) {
this.num = num;
}
#Override
public void run() {
System.out.println("Starting job: " + num);
try {
Thread.sleep(2000);
System.out.println("end job:" + num);
String result = "result " + num; // how to pass all the results back to the caller
} catch (Exception e) {
e.printStackTrace();
}
}
}
Worker Test
public class WorkerTest {
private static List<String> result = new ArrayList<>();
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
Runnable worker = new Worker(i);
executorService.execute(worker);
}
executorService.shutdown();
while(!executorService.isTerminated());
}
}
Here is your complete code
public class WorkerTest {
private static List result = new ArrayList<>();
public static void main(String[] args) throws Exception {
Future[] futures = new Future[10];
ExecutorService ex = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
Callable worker = new Worker(i);
futures[i] = ex.submit(worker);
}
for (int i = 0; i < 10; i++) {
String resultString = (String) futures[i].get();
System.out.println(resultString);
}
ex.shutdown();
while (!ex.isTerminated());
}
}
class Worker implements Callable<String> {
private final int num;
public Worker(int num) {
super();
this.num = num;
}
#Override
public String call() throws Exception {
String result = null;
System.out.println("starting job " + num);
try {
Thread.sleep(2000);
System.out.println("end job " + num);
result = "result" + num;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
Or you can do this way if you want to store results in list.
public class ExecutorTest {
private static List<String> result = new ArrayList<>();
public static void main(String[] args) throws Exception {
ExecutorService ex = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
Callable worker = new Worker(i);
Future<String> stringResult= ex.submit(worker);
String output = stringResult.get();
result.add(output);
System.out.println(output);
}
ex.shutdown();
while (!ex.isTerminated());
System.out.println("All results received frmo executor service ");
System.out.println(result);
}
}
Instead of implementing Runnable you should implement Callable and then use a method returning a Future
public class Worker implements Callable<String> {
#Override
public String call() {
return "123";
}
}
ExecutorService es = Executors.newFixedThreadPool(5);
Future<?> f = es.submit(new Worker());
String result = f.get(); // 123
> I can't wrap my head around [Futures].
Maybe a brief glimpse behind the curtain would help
Future is an interface, but there is some standard library class, whose name we do not know, that implements Future. Let's pretend it's called FutureImpl.
A FutureImpl instance has a get() method that is specified by the Future API, and it has another method that we can't see, but let's call it put(x).
When Karol Dowbecki's example code submits a task to the executor service, the executor service creates a new FutureImpl instance and does two things with it:
It gives a reference to the worker thread that is going to execute your task, and,
It returns a reference from the es.submit(...) call.
Future<?> f = es.submit(...);
The worker thread will call the task function that you give it, and then it will take the returned value, and stash it in the FutureImpl object:
futureImpl.put(task.Call());
Note! f and futureImpl are two different names for the same object. The only difference is, the worker thread knows that it is an instance of the FutureImpl class, but the main thread only knows that it is an instance of some class that implements Future.
Anyway, back to the main thread... It can do other stuff while the worker is doing its thing, and then eventually, the main thread can try to retrieve the value:
String result = f.get();
If the task has already completed, and the worker has already called futureImpl.put(...) before the main thread calls f.get() then f.get() will immediately return the value. But, if the main thread calls f.get() first, then the get() call will wait until the worker thread completes the task and stashes the value.

How to pass a parameter to a thread and get a return value?

public class CalculationThread implements Runnable {
int input;
int output;
public CalculationThread(int input)
{
this.input = input;
}
public void run() {
output = input + 1;
}
public int getResult() {
return output;
}
}
Somewhere else:
Thread thread = new Thread(new CalculationThread(1));
thread.start();
int result = thread.getResult();
Of course, thread.getResult() doesn't work (it tries to invoke this method from the Thread class).
You get what I want. How can I achieve this in Java?
This a job for thread pools. You need to create a Callable<R> which is Runnable returning a value and send it to a thread pool.
The result of this operation is a Future<R> which is a pointer to this job which will contain a value of the computation, or will not if the job fails.
public static class CalculationJob implements Callable<Integer> {
int input;
public CalculationJob(int input) {
this.input = input;
}
#Override
public Integer call() throws Exception {
return input + 1;
}
}
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(4);
Future<Integer> result = executorService.submit(new CalculationJob(3));
try {
Integer integer = result.get(10, TimeUnit.MILLISECONDS);
System.out.println("result: " + integer);
} catch (Exception e) {
// interrupts if there is any possible error
result.cancel(true);
}
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.SECONDS);
}
Prints:
result: 4
The accepted answer is great. But it is not the simplest approach. There's no real need to use an ExecutorService if you just want to wait for the result of a thread. You can simply use java.util.concurrent.FutureTask, which is basically a Runnable wrapping a Callable which also implements the Future interface.
So step 1 is still make the calculation a Callable :
public class Calculation implements Callable<Integer> {
private final int input;
public Calculation(int input) {
this.input = input;
}
#Override
public Integer call() throws Exception {
return input + 1;
}
}
So where you need the asynchronous calculation you can do :
FutureTask<Integer> task = new FutureTask<>(new Calculation(1561));
new Thread(task).start();
// ... do other stuff
// when I really need the result :
try {
int result = task.get(); // this will wait for the task to finish, if it hasn't yet.
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
e.getCause().printStackTrace(); // e.getCause() holds the exception that happened on the calculation thread
}
What the ExecutorService adds is managing a pool of threads to run the task on, but under the hood of an ExecutorService, basically the same thing happens.
You are looking for Callable. It's a Runnable on steroids, it can return a result. Check the javadoc:http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Callable.html
Here is a tutorial: http://www.journaldev.com/1090/java-callable-future-example
Old school style
public class CalculationThread extends Thread {
int input;
int output;
public CalculationThread(int input){
this.input = input;
}
public void run() {
output = input + 1;
}
public int getResult() {
return output;
}
}
CalculationThread thread = new CalculationThread(1);
thread.start();
thread.join();
int result = thread.getResult();
Use constructor and pass value by reference.
public CalculationThread(int[] input)
Do you want to pass the value of int to the thread called CalculationThread you should create a thread but if you pass a parameter by value the thread can use that value but you can't get the data back. Passing it by reference you can modify the value but not reference in the thread and the reference if it's available to both threads point to the value which is modifiable in both threads. Of cause you code should be synchronized to share the same reference.

Waiting on a list of Future

I have a method which returns a List of futures
List<Future<O>> futures = getFutures();
Now I want to wait until either all futures are done processing successfully or any of the tasks whose output is returned by a future throws an exception. Even if one task throws an exception, there is no point in waiting for the other futures.
Simple approach would be to
wait() {
For(Future f : futures) {
try {
f.get();
} catch(Exception e) {
//TODO catch specific exception
// this future threw exception , means somone could not do its task
return;
}
}
}
But the problem here is if, for example, the 4th future throws an exception, then I will wait unnecessarily for the first 3 futures to be available.
How to solve this? Will count down latch help in any way? I'm unable to use Future isDone because the java doc says
boolean isDone()
Returns true if this task completed. Completion may be due to normal termination, an exception, or cancellation -- in all of these cases, this method will return true.
You can use a CompletionService to receive the futures as soon as they are ready and if one of them throws an exception cancel the processing. Something like this:
Executor executor = Executors.newFixedThreadPool(4);
CompletionService<SomeResult> completionService =
new ExecutorCompletionService<SomeResult>(executor);
//4 tasks
for(int i = 0; i < 4; i++) {
completionService.submit(new Callable<SomeResult>() {
public SomeResult call() {
...
return result;
}
});
}
int received = 0;
boolean errors = false;
while(received < 4 && !errors) {
Future<SomeResult> resultFuture = completionService.take(); //blocks if none available
try {
SomeResult result = resultFuture.get();
received ++;
... // do something with the result
}
catch(Exception e) {
//log
errors = true;
}
}
I think you can further improve to cancel any still executing tasks if one of them throws an error.
If you are using Java 8 then you can do this easier with CompletableFuture and CompletableFuture.allOf, which applies the callback only after all supplied CompletableFutures are done.
// Waits for *all* futures to complete and returns a list of results.
// If *any* future completes exceptionally then the resulting future will also complete exceptionally.
public static <T> CompletableFuture<List<T>> all(List<CompletableFuture<T>> futures) {
CompletableFuture[] cfs = futures.toArray(new CompletableFuture[futures.size()]);
return CompletableFuture.allOf(cfs)
.thenApply(ignored -> futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList())
);
}
Use a CompletableFuture in Java 8
// Kick of multiple, asynchronous lookups
CompletableFuture<User> page1 = gitHubLookupService.findUser("Test1");
CompletableFuture<User> page2 = gitHubLookupService.findUser("Test2");
CompletableFuture<User> page3 = gitHubLookupService.findUser("Test3");
// Wait until they are all done
CompletableFuture.allOf(page1,page2,page3).join();
logger.info("--> " + page1.get());
You can use an ExecutorCompletionService. The documentation even has an example for your exact use-case:
Suppose instead that you would like to use the first non-null result of the set of tasks, ignoring any that encounter exceptions, and cancelling all other tasks when the first one is ready:
void solve(Executor e, Collection<Callable<Result>> solvers) throws InterruptedException {
CompletionService<Result> ecs = new ExecutorCompletionService<Result>(e);
int n = solvers.size();
List<Future<Result>> futures = new ArrayList<Future<Result>>(n);
Result result = null;
try {
for (Callable<Result> s : solvers)
futures.add(ecs.submit(s));
for (int i = 0; i < n; ++i) {
try {
Result r = ecs.take().get();
if (r != null) {
result = r;
break;
}
} catch (ExecutionException ignore) {
}
}
} finally {
for (Future<Result> f : futures)
f.cancel(true);
}
if (result != null)
use(result);
}
The important thing to notice here is that ecs.take() will get the first completed task, not just the first submitted one. Thus you should get them in the order of finishing the execution (or throwing an exception).
If you are using Java 8 and don't want to manipulate CompletableFutures, I have written a tool to retrieve results for a List<Future<T>> using streaming. The key is that you are forbidden to map(Future::get) as it throws.
public final class Futures
{
private Futures()
{}
public static <E> Collector<Future<E>, Collection<E>, List<E>> present()
{
return new FutureCollector<>();
}
private static class FutureCollector<T> implements Collector<Future<T>, Collection<T>, List<T>>
{
private final List<Throwable> exceptions = new LinkedList<>();
#Override
public Supplier<Collection<T>> supplier()
{
return LinkedList::new;
}
#Override
public BiConsumer<Collection<T>, Future<T>> accumulator()
{
return (r, f) -> {
try
{
r.add(f.get());
}
catch (InterruptedException e)
{}
catch (ExecutionException e)
{
exceptions.add(e.getCause());
}
};
}
#Override
public BinaryOperator<Collection<T>> combiner()
{
return (l1, l2) -> {
l1.addAll(l2);
return l1;
};
}
#Override
public Function<Collection<T>, List<T>> finisher()
{
return l -> {
List<T> ret = new ArrayList<>(l);
if (!exceptions.isEmpty())
throw new AggregateException(exceptions, ret);
return ret;
};
}
#Override
public Set<java.util.stream.Collector.Characteristics> characteristics()
{
return java.util.Collections.emptySet();
}
}
This needs an AggregateException that works like C#'s
public class AggregateException extends RuntimeException
{
/**
*
*/
private static final long serialVersionUID = -4477649337710077094L;
private final List<Throwable> causes;
private List<?> successfulElements;
public AggregateException(List<Throwable> causes, List<?> l)
{
this.causes = causes;
successfulElements = l;
}
public AggregateException(List<Throwable> causes)
{
this.causes = causes;
}
#Override
public synchronized Throwable getCause()
{
return this;
}
public List<Throwable> getCauses()
{
return causes;
}
public List<?> getSuccessfulElements()
{
return successfulElements;
}
public void setSuccessfulElements(List<?> successfulElements)
{
this.successfulElements = successfulElements;
}
}
This component acts exactly as C#'s Task.WaitAll. I am working on a variant that does the same as CompletableFuture.allOf (equivalento to Task.WhenAll)
The reason why I did this is that I am using Spring's ListenableFuture and don't want to port to CompletableFuture despite it is a more standard way
In case that you want combine a List of CompletableFutures, you can do this :
List<CompletableFuture<Void>> futures = new ArrayList<>();
// ... Add futures to this ArrayList of CompletableFutures
// CompletableFuture.allOf() method demand a variadic arguments
// You can use this syntax to pass a List instead
CompletableFuture<Void> allFutures = CompletableFuture.allOf(
futures.toArray(new CompletableFuture[futures.size()]));
// Wait for all individual CompletableFuture to complete
// All individual CompletableFutures are executed in parallel
allFutures.get();
For more details on Future & CompletableFuture, useful links:
1. Future: https://www.baeldung.com/java-future
2. CompletableFuture: https://www.baeldung.com/java-completablefuture
3. CompletableFuture: https://www.callicoder.com/java-8-completablefuture-tutorial/
I've got a utility class that contains these:
#FunctionalInterface
public interface CheckedSupplier<X> {
X get() throws Throwable;
}
public static <X> Supplier<X> uncheckedSupplier(final CheckedSupplier<X> supplier) {
return () -> {
try {
return supplier.get();
} catch (final Throwable checkedException) {
throw new IllegalStateException(checkedException);
}
};
}
Once you have that, using a static import, you can simple wait for all futures like this:
futures.stream().forEach(future -> uncheckedSupplier(future::get).get());
you can also collect all their results like this:
List<MyResultType> results = futures.stream()
.map(future -> uncheckedSupplier(future::get).get())
.collect(Collectors.toList());
Just revisiting my old post and noticing that you had another grief:
But the problem here is if, for example, the 4th future throws an exception, then I will wait unnecessarily for the first 3 futures to be available.
In this case, the simple solution is to do this in parallel:
futures.stream().parallel()
.forEach(future -> uncheckedSupplier(future::get).get());
This way the first exception, although it will not stop the future, will break the forEach-statement, like in the serial example, but since all wait in parallel, you won't have to wait for the first 3 to complete.
maybe this would help (nothing would replaced with raw thread, yeah!)
I suggest run each Future guy with a separated thread (they goes parallel), then when ever one of the got error, it just signal the manager(Handler class).
class Handler{
//...
private Thread thisThread;
private boolean failed=false;
private Thread[] trds;
public void waitFor(){
thisThread=Thread.currentThread();
List<Future<Object>> futures = getFutures();
trds=new Thread[futures.size()];
for (int i = 0; i < trds.length; i++) {
RunTask rt=new RunTask(futures.get(i), this);
trds[i]=new Thread(rt);
}
synchronized (this) {
for(Thread tx:trds){
tx.start();
}
}
for(Thread tx:trds){
try {tx.join();
} catch (InterruptedException e) {
System.out.println("Job failed!");break;
}
}if(!failed){System.out.println("Job Done");}
}
private List<Future<Object>> getFutures() {
return null;
}
public synchronized void cancelOther(){if(failed){return;}
failed=true;
for(Thread tx:trds){
tx.stop();//Deprecated but works here like a boss
}thisThread.interrupt();
}
//...
}
class RunTask implements Runnable{
private Future f;private Handler h;
public RunTask(Future f,Handler h){this.f=f;this.h=h;}
public void run(){
try{
f.get();//beware about state of working, the stop() method throws ThreadDeath Error at any thread state (unless it blocked by some operation)
}catch(Exception e){System.out.println("Error, stopping other guys...");h.cancelOther();}
catch(Throwable t){System.out.println("Oops, some other guy has stopped working...");}
}
}
I have to say the above code would error(didn't check), but I hope I could explain the solution. please have a try.
/**
* execute suppliers as future tasks then wait / join for getting results
* #param functors a supplier(s) to execute
* #return a list of results
*/
private List getResultsInFuture(Supplier<?>... functors) {
CompletableFuture[] futures = stream(functors)
.map(CompletableFuture::supplyAsync)
.collect(Collectors.toList())
.toArray(new CompletableFuture[functors.length]);
CompletableFuture.allOf(futures).join();
return stream(futures).map(a-> {
try {
return a.get();
} catch (InterruptedException | ExecutionException e) {
//logger.error("an error occurred during runtime execution a function",e);
return null;
}
}).collect(Collectors.toList());
};
The CompletionService will take your Callables with the .submit() method and you can retrieve the computed futures with the .take() method.
One thing you must not forget is to terminate the ExecutorService by calling the .shutdown() method. Also you can only call this method when you have saved a reference to the executor service so make sure to keep one.
Example code - For a fixed number of work items to be worked on in parallel:
ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
CompletionService<YourCallableImplementor> completionService =
new ExecutorCompletionService<YourCallableImplementor>(service);
ArrayList<Future<YourCallableImplementor>> futures = new ArrayList<Future<YourCallableImplementor>>();
for (String computeMe : elementsToCompute) {
futures.add(completionService.submit(new YourCallableImplementor(computeMe)));
}
//now retrieve the futures after computation (auto wait for it)
int received = 0;
while(received < elementsToCompute.size()) {
Future<YourCallableImplementor> resultFuture = completionService.take();
YourCallableImplementor result = resultFuture.get();
received ++;
}
//important: shutdown your ExecutorService
service.shutdown();
Example code - For a dynamic number of work items to be worked on in parallel:
public void runIt(){
ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
CompletionService<CallableImplementor> completionService = new ExecutorCompletionService<CallableImplementor>(service);
ArrayList<Future<CallableImplementor>> futures = new ArrayList<Future<CallableImplementor>>();
//Initial workload is 8 threads
for (int i = 0; i < 9; i++) {
futures.add(completionService.submit(write.new CallableImplementor()));
}
boolean finished = false;
while (!finished) {
try {
Future<CallableImplementor> resultFuture;
resultFuture = completionService.take();
CallableImplementor result = resultFuture.get();
finished = doSomethingWith(result.getResult());
result.setResult(null);
result = null;
resultFuture = null;
//After work package has been finished create new work package and add it to futures
futures.add(completionService.submit(write.new CallableImplementor()));
} catch (InterruptedException | ExecutionException e) {
//handle interrupted and assert correct thread / work packet count
}
}
//important: shutdown your ExecutorService
service.shutdown();
}
public class CallableImplementor implements Callable{
boolean result;
#Override
public CallableImplementor call() throws Exception {
//business logic goes here
return this;
}
public boolean getResult() {
return result;
}
public void setResult(boolean result) {
this.result = result;
}
}
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Stack2 {
public static void waitFor(List<Future<?>> futures) {
List<Future<?>> futureCopies = new ArrayList<Future<?>>(futures);//contains features for which status has not been completed
while (!futureCopies.isEmpty()) {//worst case :all task worked without exception, then this method should wait for all tasks
Iterator<Future<?>> futureCopiesIterator = futureCopies.iterator();
while (futureCopiesIterator.hasNext()) {
Future<?> future = futureCopiesIterator.next();
if (future.isDone()) {//already done
futureCopiesIterator.remove();
try {
future.get();// no longer waiting
} catch (InterruptedException e) {
//ignore
//only happen when current Thread interrupted
} catch (ExecutionException e) {
Throwable throwable = e.getCause();// real cause of exception
futureCopies.forEach(f -> f.cancel(true));//cancel other tasks that not completed
return;
}
}
}
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(3);
Runnable runnable1 = new Runnable (){
public void run(){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
}
};
Runnable runnable2 = new Runnable (){
public void run(){
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
};
Runnable fail = new Runnable (){
public void run(){
try {
Thread.sleep(1000);
throw new RuntimeException("bla bla bla");
} catch (InterruptedException e) {
}
}
};
List<Future<?>> futures = Stream.of(runnable1,fail,runnable2)
.map(executorService::submit)
.collect(Collectors.toList());
double start = System.nanoTime();
waitFor(futures);
double end = (System.nanoTime()-start)/1e9;
System.out.println(end +" seconds");
}
}
This is what i use to wait for a certain time on a list of futures. I think its cleaner.
CountDownLatch countDownLatch = new CountDownLatch(partitions.size());
// Some parallel work
for (Something tp : somethings) {
completionService.submit(() -> {
try {
work(something)
} catch (ConnectException e) {
} finally {
countDownLatch.countDown();
}
});
}
try {
if (!countDownLatch.await(secondsToWait, TimeUnit.SECONDS)){
}
} catch (InterruptedException e) {
}
A Guava-based solution can be implemented using Futures.FutureCombiner.
Here is the code example given in the javadoc:
final ListenableFuture<Instant> loginDateFuture =
loginService.findLastLoginDate(username);
final ListenableFuture<List<String>> recentCommandsFuture =
recentCommandsService.findRecentCommands(username);
ListenableFuture<UsageHistory> usageFuture =
Futures.whenAllSucceed(loginDateFuture, recentCommandsFuture)
.call(
() ->
new UsageHistory(
username,
Futures.getDone(loginDateFuture),
Futures.getDone(recentCommandsFuture)),
executor);
For more info, see the ListenableFutureExplained section of the user's guide.
If you're curious about how it works under the hood, I suggest looking at this part of the source code: AggregateFuture.java#L127-L186

Categories