我试图以线程安全的方式延迟初始化 map 。我在initialization-on-demand holder idiom之后提出了这个:
private static class NameIndexMapHolder {
private static final Map<String, Long> NAME_INDEX_MAP;
static {
Map<String, Long> map = new HashMap<>();
map.put("John", 3424534643);
map.put("Jane", 4328759749);
NAME_INDEX_MAP = Collections.unmodifiableMap(map);
}
}
public static Map<String, Long> getNameIndexMap() {
return NameIndexMapHolder.NAME_INDEX_MAP;
}
这行得通吗?它是线程安全的吗?从我阅读的内容来看,这仅适用于Singletons。我读过的唯一其他选择是双重检查锁定,它似乎有其自身的问题。
最佳答案
是的,这是线程安全和惰性的。
首先,让我们看一下它是否是线程安全的:
NAME_INDEX_MAP
的引用吗? 编号在静态初始化程序中发生,仅在初始化类(JLS 8.7)时执行。类初始化使用同步来确保只有一个线程将执行初始化程序(JLS 12.4.2)。 那么,这是懒惰的吗?是的;仅在首次访问该类的任何成员之前立即进行类初始化(JLS 12.4.1),在这种情况下,您只有一个字段。因此,初始化只会在您第一次访问
NAME_INDEX_MAP
之前立即进行,这是您想要的惰性。