Java ClassLoading 是单线程的吗?
Is Java ClassLoading SingleThreaded?
在阅读多线程时,我了解到单例需要双重锁定检查和单例引用声明为 volatile 以便
- 避免了同步开销
- 多线程没有创建单例的多个实例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。该页面很好地解释了它如何替代您提到的双重锁定机制。
- Class 加载为 not necessarily single threaded. Since Java 7,
ClassLoader
s can mark themselves as parallel capable。
- 在静态初始化器中实例化单例是可以的。主要缺点是这些初始化是 eager, as opposed to lazy. This can be mitigated by the using the initialization on demand idiom。但是请注意,可以通过创建自定义
ClassLoader
. 来 运行 两次静态初始化器
在阅读多线程时,我了解到单例需要双重锁定检查和单例引用声明为 volatile 以便
- 避免了同步开销
- 多线程没有创建单例的多个实例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。该页面很好地解释了它如何替代您提到的双重锁定机制。
- Class 加载为 not necessarily single threaded. Since Java 7,
ClassLoader
s can mark themselves as parallel capable。 - 在静态初始化器中实例化单例是可以的。主要缺点是这些初始化是 eager, as opposed to lazy. This can be mitigated by the using the initialization on demand idiom。但是请注意,可以通过创建自定义
ClassLoader
. 来 运行 两次静态初始化器