有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java重置用doublecheck习惯用法加载的字段lazyloaded

考虑“对实例字段进行惰性初始化的双检查习惯用法”:

// 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;
}

这是重置字段的标准方法吗?安全吗?有陷阱吗?我这样问是因为布洛赫对双重检查的延迟加载给出了以下警告:“这个习惯用法非常快速,但也非常复杂和微妙,所以不要试图以任何方式修改它。只是复制和粘贴——通常不是一个好主意,但在这里是合适的。”

提前谢谢, 来自喜马拉雅山脉的普拉亚


共 (2) 个答案

  1. # 1 楼答案

    我认为reset()方法不正确。如果你阅读第71项,你会发现:

    {bq 1}$

    延迟初始化并不认为字段可能会更改。如果这些运算符之间的字段设置为空:

    FieldType result = field;
    if (result == null) { // First check (no locking)

    getField()提供了错误的结果

  2. # 2 楼答案

    我认为这应该是安全的,但这只是因为您将字段存储在局部变量中。完成后,即使另一个线程正在中途重置字段的值,局部变量引用也无法神奇地变为null