Java 我是否需要为每个线程创建新的可调用对象?
这里有两种选择 1) 创建一个可调用文件并多次提交Java 我是否需要为每个线程创建新的可调用对象?,java,multithreading,Java,Multithreading,这里有两种选择 1) 创建一个可调用文件并多次提交 Callable<String> callable = new MyCallable(); for(int i=0; i< 100; i++){ Future<String> future = executor.submit(callable); list.add(future); } Callable Callable=new My
Callable<String> callable = new MyCallable();
for(int i=0; i< 100; i++){
Future<String> future = executor.submit(callable);
list.add(future);
}
Callable Callable=new MyCallable();
对于(int i=0;i<100;i++){
未来=执行人提交(可调用);
增加(未来);
}
2) 为每个线程创建多个可调用项
for(int i=0; i< 100; i++){
Future<String> future = executor.submit(new MyCallable());
list.add(future);
}
for(int i=0;i<100;i++){
Future=executor.submit(new MyCallable());
增加(未来);
}
最佳做法是什么 如果你的
MyCallable
是线程安全类,那么你可以重用它的同一个实例,否则,你将得到竞争条件和不一致的结果
换句话说,如果您的MyCallable
试图保持任何未正确同步的状态,则无法使用同一实例
例如,在下面的MyCallable
类中,您不能跨多个线程重用同一实例(即,您不能像executor.submit(singleInstance)
那样共享它):
因此,这里需要注意的重要一点是,如果您想重用相同的
Callable
实例,则需要确保它是线程安全的。否则,您需要多个可调用的
实例才能提交到ExecutorService
您需要不同的可调用对象。谢谢。我就是这么想的。然而,这里有一个让我困惑的例子。它使用一个callable@jn1kk-这取决于该类的功能。从多个线程调用同一个可调用函数本身并没有什么错,我觉得这没什么意义。用多个线程调用同一个可调用函数在“逻辑上”是如何被接受的?可调用对象在被线程使用时有其状态,然后会出现不同的线程并尝试使用相同的可调用对象。如果在每个线程中没有执行相同的操作,则可以使用单个可调用实例。Callable
中没有状态,它只需要提供call()
方法的实现。不管有多少线程使用它。
//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);
}
}
//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);
}
}