java – 多线程应用程序中的不可变对象 – 它是如何工作的?

我有这个代码将在多线程应用程序中工作.

我知道不可变对象是线程安全的,因为它的状态不能改变.如果我们有易失性参考,如果改变了,例如

MyImmutableObject state = MyImmutableObject.newInstance(oldState,newArgs);即如果一个线程想要更​​新状态,它必须创建新的不可变对象,用旧状态和一些新的状态参数初始化它,这对所有其他线程都是可见的.

但问题是,如果一个thread2用该状态启动长操作,在其中间thread1用新实例更新状态,会发生什么? Thread2将使用对旧对象状态的引用,即它将使用不一致的状态?或者thread2会看到thread1所做的更改,因为对state的引用是volatile,在这种情况下,thread1可以在其长操作的第一部分中使用旧状态,在第二部分中可以使用新状态,这是不正确的?

State state = cache.get(); //t1 
Result result1 = DoSomethingWithState(state); //t1 
        State state = cache.get(); //t2
    ->longOperation1(state); //t1
        Result result2 = DoSomethingWithState(state); //t2
             ->longOperation1(state); //t2
   ->longOperation2(state);//t1
cache.update(result1); //t1 
             ->longOperation2(state);//t2
        cache.update(result2);//t2

Result DoSomethingWithState(State state) {
    longOperation1(state);
    //Imaging Thread1 finish here and update state, when Thread2 is going to execute next method
    longOperation2(state);
return result;
}

class cache {
     private volatile State state = State.newInstance(null, null);

    update(result) {
        this.state = State.newInstance(result.getState, result.getNewFactors);

    get(){
       return state;
    }

 }

最佳答案

But the reference is volatile, isn’t it making visible the new object state … to the other threads?

不会.当对该字段的每次后续读取写入volatile字段happens-before时,另一个线程必须重新读取该字段以获取新值.

点赞