java - 我需要为每个线程创建新的 Callable 对象吗?

标签 java multithreading

这里有两个选项

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

如果你替换 intAtomicInteger ,如下所示,那么您可以重复使用同一个实例:

//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/

相关文章:

java - ExecutorService和ForkJoinPool

java - Java 的 Enum<?> 是什么意思?为什么它与 Enum 不兼容?

java - hibernate JPA IdentifierGenerationException : null id generated for class with @embeddedid

java - 有没有办法在不安装 STS 的情况下在 Eclipse 中安装 Grails 支持?

java - 如何立即从另一个线程使 TestNG 测试失败?

c# - 为什么 Timer 没有属性,初始化后如何获取它的时间间隔?

java - JSP 中的文档编辑器

java - 如何检查它是否绘制(java 游戏)

python-3.x - 让某种形式的 keras 多处理/线程在 Windows 上工作

c++ - 多线程同步