轉自:http://blog.sina.com.cn/s/blog_75247c770100yxpb.htmlhtml
面試的時候,經常會被問到這樣一個問題:請您寫出一個單例模式(Singleton Pattern)吧。好吧,寫就寫,這還不容易。順手寫一個:面試
1 //飢餓模式 2 public final class EagerSingleton 3 { 4 private static EagerSingleton singObj = new EagerSingleton(); 5 6 private EagerSingleton(){ 7 } 8 9 public static EagerSingleton getSingleInstance(){ 10 return singObj; 11 } 12 }
這種寫法就是所謂的飢餓模式,每一個對象在沒有使用以前就已經初始化了。這就可能帶來潛在的性能問題:若是這個對象很大呢?沒有使用這個對象以前,就把它加載到了內存中去是一種巨大的浪費。安全
1 //懶漢模式 2 public final class LazySingleton 3 { 4 private static LazySingleton singObj = null; 5 6 private LazySingleton(){ 7 } 8 9 public static LazySingleton getSingleInstance(){ 10 if(null == singObj ) singObj = new LazySingleton(); 11 return singObj; 12 } 13 }
這種寫法就是所謂的懶漢模式。它使用了延遲加載來保證對象在沒有使用以前,是不會進行初始化的。併發
1 //懶漢模式加Synchronized 2 public final class ThreadSafeSingleton 3 { 4 private static ThreadSafeSingleton singObj = null; 5 6 private ThreadSafeSingleton(){ 7 } 8 9 public static Synchronized ThreadSafeSingleton getSingleInstance(){ 10 if(null == singObj ) singObj = new ThreadSafeSingleton(); 11 return singObj; 12 } 13 }
1 //雙重檢查鎖 2 public final class DoubleCheckedSingleton 3 { 4 private static DoubleCheckedSingletonsingObj = null; 5 6 private DoubleCheckedSingleton(){ 7 } 8 9 public static DoubleCheckedSingleton getSingleInstance(){ 10 if(null == singObj ) { 11 Synchronized(DoubleCheckedSingleton.class){ 12 if(null == singObj) 13 singObj = new DoubleCheckedSingleton(); 14 } 15 } 16 return singObj; 17 } 18 }
這種寫法使得只有在加載新的對象進行同步,在加載完了以後,其餘線程在第九行就能夠判斷跳過鎖的的代價直接到第15行代碼了。作到很好的併發度。性能
1 //Initialization on Demand Holder 2 public class Singleton 3 { 4 private static class SingletonHolder 5 { 6 public final static Singleton instance = new Singleton(); 7 } 8 9 public static Singleton getInstance() 10 { 11 return SingletonHolder.instance; 12 } 13 }