Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我是否需要为每个线程创建新的可调用对象?_Java_Multithreading - Fatal编程技术网

Java 我是否需要为每个线程创建新的可调用对象?

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

这里有两种选择

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 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);
    }
}