les*_*es2 5 java locking thread-safety double-checked-locking
考虑"对实例字段的延迟初始化进行双重检查":
// Item 71 in Effective Java copied from this interview with Bloch. private volatile FieldType field; FieldType getField() { FieldType result = field; if (result == null) { // First check (no locking) synchronized(this) { result = field; if (result == null) // Second check (with locking) field = result = computeFieldValue(); } } return result; }
我希望能够以安全的方式重置字段(强制它再次从数据库加载,在我的情况下).我假设我们可以通过重置方法来做到这一点:
void reset() { field = null; }
这是重置场地的标准方法吗?安全吗?任何陷阱?我问,因为布洛赫发出了关于双重检查懒惰加载的以下警告:"成语非常快,但也很复杂和细腻,所以不要试图以任何方式修改它.只需复制和粘贴 - 通常这不是一个好主意,但在这里是合适的."
在此先感谢喜马拉雅山脉的Playa.
是的,这是线程安全的。
同步块是为了防止多个线程不必要的调用computeFieldValue()
。由于是 易失性的,因此和field
中的访问都是有序的。reset
getField
如果第一次检查非空,getField
则完成;result
被返回。
否则,将获取锁,排除可能将该字段设置为非空的任何其他线程,但允许任何线程设置field
为空。如果任何线程确实设置field
为 null,则不应发生任何更改;这就是使线程进入同步块的条件。如果另一个线程在当前线程检查后已经获取了锁,并将该字段设置为非空值,则第二次检查将检测到这一点。
归档时间: |
|
查看次数: |
624 次 |
最近记录: |