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

时间:2017-02-24 18:13:45

标签: java multithreading thread-safety immutability

假设多个线程使用相同的Configuration对象,有时从中读取真正的不可变对象。此外,对不可变对象的引用可能会更新。

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;
    }
}

这是一个使immutableObject访问线程安全的好方法吗?我想我甚至不需要锁,因为引用的更新是原子的,但我不确定。

1 个答案:

答案 0 :(得分:2)

  

我想我甚至不需要锁,因为引用的更新是原子的

“Atomic”意味着没有任何线程会看到immutableObject未被其他某个线程存储的值,但 时不会说

如果没有同步,则无法保证在线程A调用update()之后(如果)线程B将看到新值。说真的,Java语言规范不要求线程A 存储的值对线程B可见,除非在两个线程之间建立了“之前发生”的链。

锁定和解锁Lock对象建立了这种关系:线程A在解锁锁之前存储到任何共享变量中的任何内容都保证在线程B锁定后被线程B 看到同样的锁。

还有其他各种方法可以达到同样的效果。你可以使用synchronized,或者你可以使用一些java.utils.concurrent对象,例如一个隐式同步的队列或信号量。

或者,您可以将immutableObject声明为volatile。当线程B随后读取相同的volatile变量时,线程A存储到volatile变量中的任何内容都保证对线程B可见。