gpt4 book ai didi

java - 为什么我们不要求同步 lazy-init getter(holder 惯用语)?

转载 作者:行者123 更新时间:2023-11-30 08:44:26 25 4
gpt4 key购买 nike

我正在阅读 J. Bloch 的《effective Java》一书,现在正阅读有关惰性初始化的部分。考虑以下类:

public class LazyInit{

public static getObject(){ //Not synchronized
return Holder.o;
}

private static Object createObject(){
System.out.println("Creating started");
return new Object();
}

private static class Holder{
private static Object o = createObject();
}
}

J.布洛赫谈到这个成语:

The beauty of this idiom is that the getField method is not synchronized and performs only a field access, so lazy initialization adds practically nothing to the cost of access.

我不明白为什么安全通过。如果在字段初始化期间另一个线程尝试并发访问该字段怎么办?该对象不是在线程需要它时创建的。那么,接下来会发生什么?

最佳答案

这种方法基于 JVM 的初始化原则。

Object 的实例只会在加载Holder 类后创建。 Holder 类的加载将由类加载器在您的应用程序中第一次引用字段 o 期间执行(这里是 getObject 方法)。类加载是非并发的,因此该模式保证:

  1. Object 实例将按需创建(惰性初始化)。
  2. Object 的创建将是线程安全的。

取自wiki article :

Since the class initialization phase is guaranteed by the JLS to be serial, i.e., non-concurrent, no further synchronization is required in the static getInstance method during loading and initialization.


评论更新:

@St.Antario 找到了 formal JLS explanation对于此功能:

The procedure for initializing C is then as follows: Synchronize on the initialization lock, LC, for C. This involves waiting until the current thread can acquire LC.

关于java - 为什么我们不要求同步 lazy-init getter(holder 惯用语)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33773124/

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