Java ClassLoading是SingleThreaded吗?

时间:2015-07-22 04:44:40

标签: java multithreading singleton volatile

在阅读多线程时,我发现Singleton需要将双锁定检查和单例引用声明为volatile,以便

  1. 避免同步开销
  2. 多线程不会意外地创建多个Singleton类实例 请参考此博客。 http://javarevisited.blogspot.sg/2014/05/double-checked-locking-on-singleton-in-java.html
  3. 我心中的问题是,

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

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

2 个答案:

答案 0 :(得分:3)

  1. 类加载为not necessarily single threaded。从Java 7开始,ClassLoader可以将自己标记为parallel capable
  2. 在静态初始化程序中实例化单例是可以的。主要缺点是这些初始化是eager,而不是lazy。这可以通过使用initialization on demand idiom来缓解。但请注意,可以通过创建自定义ClassLoader来运行静态初始化程序两次。

答案 1 :(得分:1)

确实如此,你是正确的,静态初始化程序块只发生一次。事实上,它是懒惰的;它只会在实际需要该类时运行。因此,可以简单地直接实例化一个对象并为其设置一个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。该页面非常清楚地说明了它如何替代您所提到的双重锁定机制。