如果您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);
}
}
如果用AtomicInteger
替换int
而,如下图所示,那么你就可以重复使用相同的实例:
//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
,Y相同的实例你需要确保它是线程安全的。否则,您需要将多个Callable
实例提交到ExecutorService
。
您需要不同的可调用对象。 – jn1kk
谢谢。这是我的想法。然而,这里有一个例子http://www.journaldev.com/1090/java-callable-future-example让我困惑。它使用一个可调用的函数 – john
@ jn1kk - 这取决于该类的功能。从多个线程中调用相同的Callable本质上没有任何问题。 –