假设多个线程使用相同的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访问线程安全的好方法吗?我想我甚至不需要锁,因为引用的更新是原子的,但我不确定。
答案 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可见。