由于隐式内存屏障,双重检查锁定不是问题?
Double checked locking not a concern because of implicit memory barrier?
我正在审查一段代码并注意到用于设置会话锁的双重检查锁定实现:
Lock lock = getLock(mySession);
if (lock == null) {
synchronized (myService.class) {
lock = getLock(mySession);
if (lock == null) {
lock = new ReentrantLock();
setLock(mySession, lock);
}
}
}
与此代码片段一起有一条评论说开发人员假设该属性存在内存屏障:CPU 将刷新其缓存并直接从主内存读取值。
这是一个很好的假设,还是最好的做法仍然是将 'lock' 定义为 volatile 以保证它?
假设您的代码是块或方法范围的:
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);
}
}
}
//...
}
双重检查问题根本不适用于它,因为lock
是一个局部变量(分配在线程的堆栈上),所以每个线程都看到它自己的副本,并且没有并发访问它(这是双重检查问题的必要前提)。
我正在审查一段代码并注意到用于设置会话锁的双重检查锁定实现:
Lock lock = getLock(mySession);
if (lock == null) {
synchronized (myService.class) {
lock = getLock(mySession);
if (lock == null) {
lock = new ReentrantLock();
setLock(mySession, lock);
}
}
}
与此代码片段一起有一条评论说开发人员假设该属性存在内存屏障:CPU 将刷新其缓存并直接从主内存读取值。
这是一个很好的假设,还是最好的做法仍然是将 'lock' 定义为 volatile 以保证它?
假设您的代码是块或方法范围的:
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);
}
}
}
//...
}
双重检查问题根本不适用于它,因为lock
是一个局部变量(分配在线程的堆栈上),所以每个线程都看到它自己的副本,并且没有并发访问它(这是双重检查问题的必要前提)。