简体   繁体   English

更新对不可变对象线程安全的引用

[英]Update reference to immutable object thread-safe

Suppose that multiple threads use a same Configuration object, sometimes reading a truly immutable object from it. 假设多个线程使用同一个Configuration对象,有时会从中读取一个真正不可变的对象。 Additionally, the reference to the immutable object could get updated. 此外,对不可变对象的引用可能会更新。

public class Configuration {
    private ImmutableObject immutableObject;
    private ReentrantReadWriteLock lock;

    private void update() {
        lock.writeLock().lock();
        immutableObject = getNewImmutableObject();
        lock.writeLock().unlock();
    }

    public ImmutableObject getImmutableObject() {
        ImmutableObject newRef;
        lock.readLock().lock();
        newRef = immutableObject;
        lock.readLock().unlock();
        return newRef;
    }
}

Is this a good way to make the access of immutableObject thread-safe? 这是使immutableObject线程安全访问的好方法吗? I think I don't even need the lock, because the update of the reference is atomic, but I'm not sure. 我认为我什至不需要锁,因为该引用的更新是原子的,但是我不确定。

I think I don't even need the lock, because the update of the reference is atomic 我想我什至不需要锁,因为引用的更新是原子的

"Atomic" means that no thread will ever see a value for immutableObject that was not stored by some other thread, but it does not say when . “原子”表示没有任何线程会看到immutableObject的值,该值不是由其他线程存储的,但没有说什么时候

Without the synchronization, there is no guarantee about when (if ever ) thread B will see the new value after thread A calls update() . 如果不同步,没有什么时候(如果有的话),线程B会看到新的值之后线程A调用保证update() Seriously, the Java language specification does not require that the value stored by thread A ever become visible to thread B unless some chain of "happens before" has been established between the two threads. 认真地讲,Java语言规范不要求线程A所存储的值永远对线程B可见,除非在两个线程之间建立了一些“之前发生”的链。

Locking and unlocking a Lock object establishes that relationship: Anything that thread A stores into any shared variable before it unlocks a lock is guaranteed to be seen by thread B after thread B locks the same lock. 锁定和解锁Lock对象将建立这种关系:线程A锁定相同的锁之后,线程A保证线程A在解锁之前将其存储到任何共享变量中的任何内容都可以由线程B看到。

There are various other ways to achieve the same effect. 还有多种其他方法可以达到相同的效果。 You could use synchronized , or you could use some java.utils.concurrent object such as a queue or a semaphore that implicitly synchronizes something. 您可以使用synchronized ,也可以使用一些java.utils.concurrent对象,例如隐式同步某些内容的队列或信号灯。

Or, you could declare immutableObject to be volatile . 或者,您可以将immutableObject声明为volatile Anything that thread A stores into a volatile variable is guaranteed to be visible to thread B when thread B subsequently reads the same volatile variable. 当线程B随后读取相同的volatile变量时,保证线程A存储到volatile变量中的任何内容对于线程B都是可见的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM