invokeAny 是取消线程池中的所有线程还是仅取消可调用线程?
Does invokeAny cancel all the threads in a Thread pool or only callables?
我正在创建一个固定大小的 ExecutorService
,它将被多个线程访问。
ExecutorService executorService = Executors.newFixedThreadPool(2);
然后我使用相同的 ExecutorService
从两个不同的线程调用 invokeAny
。
executorService.invokeAny(listCallables);
所以有可能在线程池中可以有多个任务从不同的线程调用。
根据 invokeAny 文档:
Upon normal or exceptional return, tasks that have not completed are cancelled.
我的问题是,在 invokeAny
的 return 成功后,它会取消线程池中的所有线程还是只取消在单独线程中调用的任务?
在 invokeAny
的正常 return 时,线程池将取消所有未完成的任务。你可以参考我的例子:
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";
}
}
主要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();
}
}
输出:
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)
可以看到,指定线程t2
休眠1秒,t1
休眠2秒。当t2
成功returns时,adpool中断执行t1
.
来自 invokeAny
在 Java 中的实施来源:
try {
....
} finally {
for (Future<T> f : futures)
f.cancel(true);
}
这意味着invokeAny
只取消已经提交给它的callable-s。
我正在创建一个固定大小的 ExecutorService
,它将被多个线程访问。
ExecutorService executorService = Executors.newFixedThreadPool(2);
然后我使用相同的 ExecutorService
从两个不同的线程调用 invokeAny
。
executorService.invokeAny(listCallables);
所以有可能在线程池中可以有多个任务从不同的线程调用。
根据 invokeAny 文档:
Upon normal or exceptional return, tasks that have not completed are cancelled.
我的问题是,在 invokeAny
的 return 成功后,它会取消线程池中的所有线程还是只取消在单独线程中调用的任务?
在 invokeAny
的正常 return 时,线程池将取消所有未完成的任务。你可以参考我的例子:
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";
}
}
主要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();
}
}
输出:
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)
可以看到,指定线程t2
休眠1秒,t1
休眠2秒。当t2
成功returns时,adpool中断执行t1
.
来自 invokeAny
在 Java 中的实施来源:
try {
....
} finally {
for (Future<T> f : futures)
f.cancel(true);
}
这意味着invokeAny
只取消已经提交给它的callable-s。