I'm creating a fixed size ExecutorService, which is going to be accessed from multiple threads.
ExecutorService executorService = Executors.newFixedThreadPool(2);
Then I'm calling invokeAny from two different threads using the same ExecutorService.
executorService.invokeAny(listCallables);
So there is a possibility that in the thread pool there can be multiple tasks called from different threads.
As per the invokeAny documentation:
Upon normal or exceptional return, tasks that have not completed are cancelled.
My question is, upon successful return of invokeAny, will it cancel all the threads which are in the thread pool or will it cancel only the tasks which are called in separate threads?
Upon normal return of invokeAny, the threadpool will cancel all uncompleted tasks. You can refer to my example:
package com.pechen;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
public class SleepSecondsCallable implements Callable<String> {
private String name;
private int seconds;
public SleepSecondsCallable(String name, int seconds) {
this.name = name;
this.seconds = seconds;
}
public String call() throws Exception {
System.out.println(name + ",begin to execute");
try {
TimeUnit.SECONDS.sleep(seconds);
} catch (InterruptedException e) {
System.out.println(name + " was disturbed during sleeping.");
e.printStackTrace();
return name + ",fails to execute";
}
return name + ",success to execute";
}
}
The main class:
package com.pechen;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newFixedThreadPool(3);
List<Callable<String>> tasks = new ArrayList<Callable<String>>();
tasks.add(new SleepSecondsCallable("t1", 2));
tasks.add(new SleepSecondsCallable("t2", 1));
String result = executorService.invokeAny(tasks);
System.out.println(result);
executorService.shutdown();
}
}
The output:
t1,begin to execute
t2,begin to execute
t2,success to execute
t1 was disturbed during sleeping.
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Unknown Source)
at java.util.concurrent.TimeUnit.sleep(Unknown Source)
at com.pechen.SleepSecondsCallable.call(SleepSecondsCallable.java:20)
at com.pechen.SleepSecondsCallable.call(SleepSecondsCallable.java:1)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
You can see, specify thread t2 to sleep for 1 second and t1 for 2. When t2 successfully returns, theadpool interupts the execution of t1.
From invokeAny implementation in Java Sources:
try {
....
} finally {
for (Future<T> f : futures)
f.cancel(true);
}
This means invokeAny cancels only the callable-s which has been submitted to it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With