Java内存模型发生-在保证线程池交互之前

帕维尔:

Java内存模型是否提供线程池交互之前发生的保证?尤其是,线程池工作线程在从工作队列中运行项目结束之前所做的写入是否对之后从队列中运行下一个项目的工作线程可见?

该规范(我个人认为该FAQ很有用:http : //www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#synchronization)指出“在A上调用start()线程发生在启动线程中的任何操作之前。 “或者简单地说,您在启动线程之前所做的任何内存写入都将在启动线程将要执行的run()方法之前执行,并且对run()方法可见。对于线程池,情况有所不同,start()通常会在进行写操作之前运行。考虑一个简单的工作流,其中将上下文对象变异并传递给下一个操作:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Main {

    private static class Container<T> {
        private T value;
        public T get() {
            return value;
        }
        public void set(T newValue) {
            value = newValue;
        }
    }

    public static void main(String[] args) {
        final Container<Integer> sharedObject = new Container<>();
        final ExecutorService executor = Executors.newFixedThreadPool(10);
        // SKIPPED: pre-warm the executor so all worker threads are start()'ed
        final Runnable read = () -> System.out.println("Got " + sharedObject.get());
        Runnable write = () -> {
            sharedObject.set(35);
            executor.execute(read);
        };
        executor.execute(write);
        // SKIPPED: wait until done
    }
}

是写sharedObject.valuewrite.run()保证是可见(不询问订货,这是显而易见的)来read.run()

(PS:我知道制作value volatile确实可以提供此保证)

更新(补充答案):软件包摘要文档,以java.util.concurrent总结该语言提供并由框架扩展的内存一致性保证:https : //docs.oracle.com/javase/7/docs/api/java/util/concurrent/package -summary.html#MemoryVisibility

斯蒂芬·C:

我认为可以保证它是可见的。ExecutorService扩展Executorjavadoc文档Executor说:

内存一致性影响:在将Runnable对象提交Executor 事件之前的线程中的操作-在对象开始执行之前(可能在另一个线程中)。

根据我的阅读,这与您的示例中发生的情况相匹配。write可运行在提交read可运行的,所以就有了之前发生在提交之前事件之间的关系write线程(即set调用),并在随后的事件read线程(即get调用)。

write可运行对象本身已提交的事实意味着对象的创建与对的调用之间发生了一件事情Containerset

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章