线程安全的单例模式(转载)
原文查看这里;
面试的时候,常常会被问到这样一个问题:请您写出一个单例模式(Singleton Pattern)吧。好吧,写就写,这还不容易。顺手写一个:
- public final class EagerSingleton
- {
- private static EagerSingleton singObj = new EagerSingleton();
- private EagerSingleton(){
- }
- public static EagerSingleton getSingleInstance(){
- return singObj;
- }
- }
- public final class LazySingleton
- {
- private static LazySingleton singObj = null;
- private LazySingleton(){
- }
- public static LazySingleton getSingleInstance(){
- if(null == singObj ) singObj = new LazySingleton();
- return singObj;
- }
- }
- public final class ThreadSafeSingleton
- {
- private static ThreadSafeSingleton singObj = null;
- private ThreadSafeSingleton(){
- }
- public static Synchronized ThreadSafeSingleton getSingleInstance(){
- if(null == singObj ) singObj = new ThreadSafeSingleton();
- return singObj;
- }
- }
- public final class DoubleCheckedSingleton
- {
- private static DoubleCheckedSingletonsingObj = null;
- private DoubleCheckedSingleton(){
- }
- public static DoubleCheckedSingleton getSingleInstance(){
- if(null == singObj ) {
- Synchronized(DoubleCheckedSingleton.class){
- if(null == singObj)
- singObj = new DoubleCheckedSingleton();
- }
- }
- return singObj;
- }
- }
- public class Singleton
- {
- private static class SingletonHolder
- {
- public final static Singleton instance = new Singleton();
- }
- public static Singleton getInstance()
- {
- return SingletonHolder.instance;
- }
- }
-------------------------------------------华丽的分割线---------------------------------------------
对最后一个还不是很了解,应该是内部类掌握的还不是很清楚。
2013/03/18 更新
Initialzation on Demand Holder:
How it works
The implementation relies on the well-specified initialization phase of execution within the Java Virtual Machine (JVM); see section 12.4 of Java Language Specification (JLS) for details.
When the class Something is loaded by the JVM, the class goes through initialization. Since the class does not have any static variables to initialize, the initialization completes trivially. The static class definition LazyHolder within it is not initialized until the JVM determines that LazyHolder must be executed. The static class LazyHolder is only executed when the static method getInstance is invoked on the class Something, and the first time this happens the JVM will load and initialize the LazyHolder class. The initialization of the LazyHolder class results in static variable INSTANCE being initialized by executing the (private) constructor for the outer class Something. 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. And since the initialization phase writes the static variable INSTANCE in a serial operation, all subsequent concurrent invocations of the getInstance will return the same correctly initialized INSTANCE without incurring any additional synchronization overhead.
When to use it
Use this pattern if the initialization of the class is expensive and it cannot be done safely at class-loading time and the initialization is highly concurrent. The crux of the pattern is the safe removal of the synchronization overhead associated with accessing a singleton instance.
When not to use it
Avoid this idiom if the construction of INSTANCE can fail. If construction of INSTANCE fails, an invocation of Something.getInstance() will result in ajava.lang.ExceptionInInitializerError error. Handling, or mishandling, of these types of construction initialization failures is a common criticism of this idiom and the singleton pattern in general.