I am reviewing a piece of code and noticed a double checked locking implementation for setting a session lock:
Lock lock = getLock(mySession);
if (lock == null) {
synchronized (myService.class) {
lock = getLock(mySession);
if (lock == null) {
lock = new ReentrantLock();
setLock(mySession, lock);
}
}
}
There was a comment along with this code snippet that said the developer assumed there was a memory barrier for the attribute: the CPU will flush its caches and read the value from main memory directly.
Is this a good assumption, or would the best practice still be to define 'lock' as volatile to guarantee it?
Assuming that your code is block or method scoped:
public void mymethod() {
//...
Lock lock = getLock(mySession);
if (lock == null) {
synchronized (myService.class) {
lock = getLock(mySession);
if (lock == null) {
lock = new ReentrantLock();
setLock(mySession, lock);
}
}
}
//...
}
The double checking issue does not apply to it at all, as lock
is a local variable (allocated on the thread's stack), so each Thread sees it's own copy of it, and there is no concurrent access to it (which is an essential precondition for the double checking issues).