单例模式的几种实现方式
生活随笔
收集整理的這篇文章主要介紹了
单例模式的几种实现方式
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
實現方式大致分為兩種
- 懶漢模式
- 餓漢模式
懶漢模式:在第一次使用該對象時,才會初始化實例,以免了資源的浪費,同時,需要考慮的是線程安全問題。
餓漢模式:在類初始化時就需要創建一個實例對象出來,當時并不一定會使用該對象,可能會造成資源的浪費,好處是不用考慮安全問題。
下面看下幾種常見的實現方式:
首先看懶漢模式:
1、線程非安全版本,可在單線程下使用
/*** 懶漢式單例,線程不安全,只有在第一次調用時才會初始化一次,* 但是線程不安全,如果在初始化時需要消耗大量的資源,則會造成資源的浪費,同時,在并發場景中,可能造成變量的變化等問題。* @author woniu**/ public class Singleton1 {private Singleton1(){}private static Singleton1 instance = null;public static Singleton1 getInstance(){if (instance == null){instance = new Singleton1();}return instance;} }關于懶漢模式的幾種線程安全版本,詳細的說明已在類中說明,不在單獨說明。
1、在getInstance方法上加同步
/*** 懶漢式單例,線程安全,與第一種無異,僅是通過synchronized,將getInstance實現為了同步方法,* 但是,這就造成了getInstance方法,僅能同時只有一個線程調用,但是,在除去第一次初始化外,我們大多數情況下,并不需要防止同步問題。* @author woniu*/ public class Singleton2 {private Singleton2(){}private static Singleton2 instance = null;public static synchronized Singleton2 getInstance(){if (instance == null){instance = new Singleton2();}return instance;} }2、雙重檢查鎖定
/*** 此方法被稱為雙重校驗鎖,在示例2的基礎之上將同步方法,修改為了同步代碼塊,僅是在需要初始化時,才需要加鎖,這樣就避免了在大多數情況下不需要同步的問題。* 關于之所以在同步方法塊中再次進行判斷的原因:根據并發編程實戰中的提到的“先檢查后執行”的操作是非原子性的,簡而言之就是,避免用一個過期的變量作為當前的判斷標準。* 連接:http://www.cnblogs.com/woniu4/p/8284244.html* @author woniu**/ public class Singleton3 {private Singleton3(){}private volatile static Singleton3 instance = null;public static Singleton3 getInstance(){if (instance == null){synchronized(Singleton3.class){if (instance == null){instance = new Singleton3();}}}return instance;} }3、靜態內部類
/*** 單例同樣可以通過內部類的方式實現,這樣就避免了同步帶來的性能開銷(雖說現在synchronize方法已經做了很大的優化,對性能的影響已經降低了很多,但終究還是有一定影響的。)* 雖說這種方式比較好,但是在我們當前項目中,似乎大家都比較懶,直接用了方法2中的模式,畢竟,當前的工程性項目,并沒有對項目性能有極高的要求。* @author woniu**/ public class Singleton4 {private Singleton4(){};private static class LasyHolder{private static final Singleton4 INSTANCE = new Singleton4();}public static Singleton4 getInstance(){return LasyHolder.INSTANCE;} }餓漢模式:
/*** 餓漢模式,通過在類初始化時,已經實例化,這樣本身就是線程安全的。* @author woniu**/ public class Singleton5 {private Singleton5(){}private static final Singleton5 INSTANCE = new Singleton5();public static Singleton5 getInstance(){return INSTANCE;} }最后有一種通過枚舉實現的方式,算是一種比較新的方式吧。當前不清楚具體歸屬類型,暫且單列出來。
/*** 枚舉模式,沒有使用過,僅是博客或者書見過這種方式,不僅能避免線程同步問題,而且還能防止反序列化重新創建新的對象,日后工作中,有類似需要單例場景中,可以考慮使用一下,寫法還是十分簡單的。* @author woniu**/ public enum Singleton6 {INSTANCE;public String testMethod(){return "test enum instance";}public static void main(String[] args){String str = INSTANCE.testMethod();System.out.println(str);} }?
轉載于:https://www.cnblogs.com/woniu4/p/8287484.html
總結
以上是生活随笔為你收集整理的单例模式的几种实现方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jdk7启动时报“java.lang.V
- 下一篇: linux-centerOs6.8安装n