單例模式一二三
阿新 • • 發佈:2017-06-11
out 支持 turn pos 系統 mod 單例 sys clas
單例模式幹的事情非常easy,就是要保證某一個對象全局唯一。 執行結果是顯示一個初始化
可是這裏存在一個問題 假設多個線程同一時候執行這段代碼,當第一個線程執行到sl=new Singleton()時(這一句還沒有執行),第二個線程檢查sl還是為null的,此時第二個線程也進來了... 然後就有多個對象了。
這樣的單例模式,我們在類載入的時候,就把類變量new出來。這樣的方式我們稱之為餓漢模式。
首先餓漢問題攻克了上面的線程問題。我最開始載入的時候就有了類變量了而且還僅僅有一個,自然不會存在線程問題了。
但這裏有個性能問題,無論我用不用這個單例類,它總會被載入內存中,因此性能是個問題。
內部類的方式攻克了上面所提的幾個問題。參考資料
http://blog.csdn.net/lovelion/article/details/7420883
對嗎? 對不正確要看標準
單例模式(Singleton Pattern):確保某一個類僅僅有一個實例,並且自行實例化並向整個系統提供這個實例。
這個類稱為單例類。它提供全局訪問的方法。單例模式是一種對象創建型模式。
看來我之前定義的不全對。
第一 保證類僅僅有一個實例
第二 類本身自己實例化(意思就是不能讓別的類來new自己)
第三 提供全局訪問的方法
OK 那我如今寫出第一種Singleton
第一種Singleton
public class Singleton{ private static Singleton sl; private Singleton(){ System.out.println("初始化"); } public static Singleton getInstance(){ if(sl==null) sl=new Singleton(); return sl; } public static void main(String[] args){ Singleton sl=Singleton.getInstance(); Singleton sl2=Singleton.getInstance(); } }
可是這裏存在一個問題 假設多個線程同一時候執行這段代碼,當第一個線程執行到sl=new Singleton()時(這一句還沒有執行),第二個線程檢查sl還是為null的,此時第二個線程也進來了... 然後就有多個對象了。
所以有
另外一種Singleton
/*** * 餓漢模式 */ public class Singleton2{ private final static Singleton2 sl2=new Singleton2(); private Singleton2(){ System.out.println("初始化"); } public static Singleton2 getInstance(){ return sl2; } public static void main(String[] args){ Singleton2 sl2=Singleton2.getInstance(); Singleton2 sl3=Singleton2.getInstance(); } }
首先餓漢問題攻克了上面的線程問題。我最開始載入的時候就有了類變量了而且還僅僅有一個,自然不會存在線程問題了。
但這裏有個性能問題,無論我用不用這個單例類,它總會被載入內存中,因此性能是個問題。
上面說了這個模式叫餓漢模式,那自然有非餓漢模式(術語叫懶漢模式)。只是在這裏我不太想和大家聊懶漢模式,太復雜,且不怎麽用。
那有沒有一種單例,既能解決第一個的線程問題,同一時候保持性能(事實上另外一種餓漢模式就不錯了,就那一個類,能拖多少性能?就算有10個,100個也不是太多)呢?並且也不像我說的那個"懶漢模式"那麽復雜呢?
答案是肯定的。
有!
內部類模式
public class Singleton3{ private static class hold{ private final static Singleton3 sl3=new Singleton3(); } private Singleton3(){ System.out.println("初始化"); } public static Singleton3 getInstance(){ return hold.sl3; } public static void main(String[] args){ Singleton3 sl3=Singleton3.getInstance(); Singleton3 sl4=Singleton3.getInstance(); System.out.println(sl3==sl4); } }關於內部類與static,final的分析,我們這裏臨時不講。
內部類的方式攻克了上面所提的幾個問題。
但也引出了一個不是問題的問題
內部類是java支持的,可是在別的語言中,不一定。
參考資料
http://blog.csdn.net/lovelion/article/details/7420883
單例模式一二三