我正在创建一个固定大小ExecutorService
,它将从多个线程访问。
ExecutorService executorService = Executors.newFixedThreadPool(2);
然后我使用相同的invokeAny
从两个不同的线程中调用ExecutorService
。
executorService.invokeAny(listCallables);
因此,在线程池中可能存在从不同线程调用的多个任务。
根据invokeAny文档:
在正常或特殊退货时,未完成的任务将被取消。
我的问题是,成功返回invokeAny
后,是否会取消线程池中的所有线程,还是仅取消在单独线程中调用的任务?
答案 0 :(得分:1)
正常返回invokeAny
后,线程池将取消所有未完成的任务。你可以参考我的例子:
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";
}
}
主要班级:
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
成功返回时,存在中断执行t1
。
答案 1 :(得分:1)
来自Java Sources中的invokeAny
实现:
try {
....
} finally {
for (Future<T> f : futures)
f.cancel(true);
}
这意味着invokeAny
仅取消已提交给它的callable-s。