JAVA设计模式之单例设计模式
? ? ? ? 單例模式,是一種常用的軟件設計模式。在它的核心結構中只包含一個被稱為單例的特殊類。通過單例模式可以保證系統中,應用該模式的類一個類只有一個實例。即一個類只有一個對象實例。
在JAVA中實現單例,必須了解JAVA內存機制,JAVA中實例對象存在于堆內存中,若要實現單例,必須滿足兩個條件:
1.限制類實例化對象。即只能產生一個對象。
2.保證外部能夠獲取這個對象,否則對象創建將毫無意義
如要滿足以上兩個條件,可以將構造方法私有化,然后在類中提供一個靜態方法獲取類實例。代碼如下
1 public class SingleTon { 2 3 private static final SingleTon single = new SingleTon(); 4 5 private SingleTon() { 6 7 } 8 9 /** 10 * 獲取一個單例對象。 11 * @return 返回SingleTon對象。 12 */ 13 public static SingleTon getInstance() { 14 return single; 15 } 16 17 }JVM加載SingleTon后,會對靜態成員做默認初始化,此時new SingleTon()創建的對象會賦值給single,類只會被加載一次,即使多次調用getInstance方法,所返回的對象也不會改變。single字段在初始化的過程中,對象就創建了,所以以上案例的代碼又稱為餓漢式。從對象的生命周期來看,類一旦加載,對象會在堆中立即創建,會浪費內存空間,因此,又存在另外一種稱為懶漢式的單例設計模式。代碼如下:
1 public class SingleTonLazy { 2 3 private static SingleTonLazy single = null; 4 5 private SingleTonLazy() { 6 7 } 8 9 /** 10 * 獲取一個單例對象。 11 * @return 返回SingleTon對象。 12 */ 13 public static SingleTonLazy getInstance() { 14 15 if (single == null) { 16 single = new SingleTonLazy(); 17 } 18 19 return single; 20 21 } 22 23 }
?
SingleTonLazy在被加載進方法區后,不會立即創建對象,而是直到getInstance方法被調用以后,對象才會被創建。這種方式可以節約內存空間,但是也存在著線程安全問題,當線程A執行到判斷對象為null,此時線程B獲得執行權,線程B判斷對象為null,此時線程A重新獲得執行權,創建對象,線程B恢復,繼續創建對象。將代碼修改如下,使用同步鎖解決線程安全問題。
1 public class SingleTonLazy { 2 3 private static SingleTonLazy single = null; 4 5 private final static Lock lock = new ReentrantLock(); 6 7 private SingleTonLazy() { 8 9 } 10 11 /** 12 * 獲取一個單例對象。 13 * @return 返回SingleTon對象。 14 */ 15 public static SingleTonLazy getInstance() { 16 17 if (single != null) { 18 return single; 19 } 20 21 lock.lock(); 22 if (single == null) { 23 single = new SingleTonLazy(); 24 } 25 lock.unlock(); 26 27 return single; 28 29 } 30 }
總結:餓漢式與懶漢式各有優缺點,但是相對來說,占用內存空間比讓cpu判斷鎖的開銷要小,所以餓漢式更使用一些。
?
轉載于:https://www.cnblogs.com/liushihu/p/8720677.html
總結
以上是生活随笔為你收集整理的JAVA设计模式之单例设计模式的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: CSS计数器(自定义列表)
- 下一篇: python学习之路day02
