以下是两个选项
1)创建一个Callable并多次提交
Callable<String> callable = new MyCallable();
for(int i=0; i< 100; i++){
Future<String> future = executor.submit(callable);
list.add(future);
}
2)为每个线程创建多个Callables
for(int i=0; i< 100; i++){
Future<String> future = executor.submit(new MyCallable());
list.add(future);
}
最佳做法是什么?
答案 0 :(得分:5)
如果您的MyCallable
线程安全类,那么您可以重复使用相同的实例,否则,您最终会遇到竞争条件且不一致结果。
换句话说,如果您的MyCallable
尝试保留任何未正确同步的状态,那么您就无法使用相同的实例。
例如,在下面的MyCallable
类中,您无法在多个线程中重复使用相同的实例(即,您无法像executor.submit(singleInstance)
那样共享它:)
//Non-Thread Safe Callable implementation
public class MyCallable implements Callable<String> {
private int i;
@Override
public String call() throws Exception {
i++; //RACE CONDITION
System.out.println(i);
return String.valueOf(i);
}
}
如果您将int
替换为AtomicInteger
,如下所示,那么您可以重复使用相同的实例:
//Thread Safe Callable implementation
public class MyThreadSafeCallable implements Callable<String> {
private AtomicInteger i = new AtomicInteger(0);
@Override
public String call() throws Exception {
int value = i.incrementAndGet();
System.out.println(value);
return String.valueOf(value);
}
}
所以,这里要注意的重点是,如果你想重用Callable
的同一个实例,你需要确保它是线程安全的。否则,您需要将多个Callable
个实例提交到ExecutorService
。