并发,对象可见性

Int*_*ger 7 java concurrency multithreading volatile

我试图弄清楚下面的代码是否存在任何潜在的并发问题.具体而言,可见性问题与volatile变量有关.易失性定义为:此变量的值永远不会被线程本地缓存:所有读取和写入将直接进入"主存储器"

public static void main(String [] args)
{
    Test test = new Test();

    // This will always single threaded
    ExecutorService ex = Executors.newSingleThreadExecutor();

    for (int i=0; i<10; ++i)
        ex.execute(test);
}

private static class Test implements Runnable {
    // non volatile variable in question
    private int state = 0;

    @Override
    public void run() {
        // will we always see updated state value? Will updating state value
        // guarantee future run's see the value?
        if (this.state != -1)
            this.state++;
    }
}
Run Code Online (Sandbox Code Playgroud)

对于上面的单线程执行程序:

是否可以使test.state非易失性?换句话说,每个连续的Test.run()(它将顺序发生而不是并发发生,因为再次执行程序是单线程的),总是会看到更新的test.state值吗?如果没有,不退出Test.run()确保所做的任何更改线程本地写回主内存?否则什么时候更改使得线程本地写回主内存,如果没有退出线程?

irr*_*ble 2

是的,即使执行器在中间替换了它的线程,它也是安全的。线程的启动/终止也是同步点。

http://java.sun.com/docs/books/jls/third_edition/html/memory.html#17.4.4

一个简单的例子:

static int state;
static public void main(String... args) {
    state = 0;                   // (1)
    Thread t = new Thread() {
        public void run() {
            state = state + 1;   // (2) 
        }
    };
    t.start();
    t.join();
    System.out.println(state);  // (3)
}
Run Code Online (Sandbox Code Playgroud)

保证 (1)、(2)、(3) 有序且行为符合预期。

对于单线程执行器,“保证任务按顺序执行”,它必须以某种方式在开始下一个任务之前检测一个任务的完成,这必须正确同步不同的run()任务