Java ClassLoading 是单线程的吗?

Is Java ClassLoading SingleThreaded?

在阅读多线程时,我了解到单例需要双重锁定检查和单例引用声明为 volatile 以便

  1. 避免了同步开销
  2. 多线程没有创建单例的多个实例class偶然考虑中 请参考此博客。 http://javarevisited.blogspot.sg/2014/05/double-checked-locking-on-singleton-in-java.html

我心中的问题是,

如果 Class 加载是单线程的,为什么我们关心多线程问题?

静态初始化程序块恰好在应用程序生命周期中只执行一次,那么为什么不使用静态初始化程序创建单例呢?

这是真的,你是对的,静态初始化程序块只发生一次。事实上,它是懒惰的;只有在实际需要 class 时才会 运行 。因此,可以简单直接地静态实例化一个对象并为其设置一个 getter 。这是使用 « Initialization On Demand Holder idiom » 演示的:

private static class LazySomethingHolder {
  public static Something something = new Something();
}

public static Something getInstance() {
  return LazySomethingHolder.something;
}

有关详细信息,请参阅 http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#dcl。该页面很好地解释了它如何替代您提到的双重锁定机制。

  1. Class 加载为 not necessarily single threaded. Since Java 7, ClassLoaders can mark themselves as parallel capable
  2. 在静态初始化器中实例化单例是可以的。主要缺点是这些初始化是 eager, as opposed to lazy. This can be mitigated by the using the initialization on demand idiom。但是请注意,可以通过创建自定义 ClassLoader.
  3. 来 运行 两次静态初始化器