这里有两个选项
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);
}
最佳实践是什么?
最佳答案
如果您的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
.
关于java - 我需要为每个线程创建新的 Callable 对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43413977/