更新对不可变对象线程安全的引用
Update reference to immutable object thread-safe
假设多个线程使用同一个 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 的访问线程安全的好方法吗?我想我什至不需要锁,因为引用的更新是原子的,但我不确定。
I think I don't even need the lock, because the update of the reference is atomic
"Atomic" 意味着没有线程会看到 immutableObject
的值未被其他线程存储,但它不会说 when .
如果没有同步,则无法保证(如果 曾经)线程 B 将在线程 A 调用 update()
后看到新值。严重的是,Java 语言规范不要求线程 A ever 存储的值对线程 B 可见,除非在 "happens before" 之间建立了一些链两个线程。
锁定和解锁 Lock
对象建立了这种关系:线程 A 在解锁锁之前存储到任何共享变量中的任何内容都保证线程 B after[=32] 可以看到=] 线程B 锁了同一个锁。
有多种其他方法可以达到相同的效果。您可以使用 synchronized
,或者您可以使用某些 java.utils.concurrent
对象,例如隐式同步某些内容的队列或信号量。
或者,您可以将 immutableObject
声明为 volatile
。当线程 B 随后读取同一个 volatile 变量时,线程 A 存储到 volatile 变量中的任何内容都保证对线程 B 可见。
假设多个线程使用同一个 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 的访问线程安全的好方法吗?我想我什至不需要锁,因为引用的更新是原子的,但我不确定。
I think I don't even need the lock, because the update of the reference is atomic
"Atomic" 意味着没有线程会看到 immutableObject
的值未被其他线程存储,但它不会说 when .
如果没有同步,则无法保证(如果 曾经)线程 B 将在线程 A 调用 update()
后看到新值。严重的是,Java 语言规范不要求线程 A ever 存储的值对线程 B 可见,除非在 "happens before" 之间建立了一些链两个线程。
锁定和解锁 Lock
对象建立了这种关系:线程 A 在解锁锁之前存储到任何共享变量中的任何内容都保证线程 B after[=32] 可以看到=] 线程B 锁了同一个锁。
有多种其他方法可以达到相同的效果。您可以使用 synchronized
,或者您可以使用某些 java.utils.concurrent
对象,例如隐式同步某些内容的队列或信号量。
或者,您可以将 immutableObject
声明为 volatile
。当线程 B 随后读取同一个 volatile 变量时,线程 A 存储到 volatile 变量中的任何内容都保证对线程 B 可见。