Reputation: 154
Suppose that multiple threads use a same Configuration object, sometimes reading a truly immutable object from it. 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? I think I don't even need the lock, because the update of the reference is atomic, but I'm not sure.
Upvotes: 1
Views: 308
Reputation: 27115
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.
Without the synchronization, there is no guarantee about when (if ever) thread B will see the new value after thread A calls 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.
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.
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.
Or, you could declare immutableObject
to be 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.
Upvotes: 2