gpt4 book ai didi

java - 使用双重检查惯用语重置延迟加载的字段

转载 作者:搜寻专家 更新时间:2023-10-31 19:51:23 25 4
gpt4 key购买 nike

考虑“双重检查实例字段延迟初始化的习惯用法”:

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

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

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

最佳答案

是的,这是线程安全的。

同步块(synchronized block)是为了防止多个线程不必要地调用computeFieldValue()。由于 field 是易变的,因此 resetgetField 中的访问都是有序的。

如果第一次检查是非空的,getField 完成; result 返回。

否则,获取一个锁,排除任何其他可能将该字段设置为非空的线程,但允许任何线程将字段设置为空。如果任何线程确实将 field 设置为 null,则应该没有任何改变;这就是让线程进入同步块(synchronized block)的条件。如果在当前线程检查后另一个线程已经获取了锁,并将该字段设置为非空值,则第二次检查将检测到。

关于java - 使用双重检查惯用语重置延迟加载的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/307073/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com