Java内存模型:保证从其他线程可见的赋值?

时间:2018-04-03 16:11:14

标签: java memory thread-safety

考虑这个程序:

public class Test {
    private int i = 1;

    public void f() {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                if (i != 2)
                    throw new AssertionError("i != 2");
            }
        };
        i = 2;
        new Thread(runnable).start();
    }
}

根据Java Memory Model,在run()中,i保证等于2,至少因为:

  

在线程happens-before上调用start()已启动线程中的任何操作。

所以i = 2 发生在 if (i != 2)之前。到目前为止,非常好。

但是如果我们在作业完成后没有开始任何线程怎么办:

public class Test {
    private static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor();
    private int i = 1;

    public void f() {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                if (i != 2)
                    throw new AssertionError("i != 2");
            }
        };
        i = 2;
        EXECUTOR.execute(runnable);
    }
}

之前的规则不适用。 保证i = 2 在{/ 1}}执行}之前发生了什么?

在创建run()之前分配变量会对发生在订单之前发生任何影响

Runnable

1 个答案:

答案 0 :(得分:3)

来自ExecutorService Javadoc:

  

在向ExecutorService提交Runnable或Callable任务之前,线程中的操作发生在该任务执行的任何操作之前。