Java 设计模式-【单例模式】
單例解決了什么問題:為了節(jié)約系統(tǒng)資源,有時需要確保系統(tǒng)中某個類只有唯一一個實(shí)例,當(dāng)這個唯一實(shí)例創(chuàng)建成功之后,我們無法再創(chuàng)建一個同類型的其他對象,所有的操作都只能基于這個唯一實(shí)例。為了確保對象的唯一性,我們可以通過單例模式來實(shí)現(xiàn),這就是單例模式的動機(jī)所在。
單例的應(yīng)用場景:一般是對于那些業(yè)務(wù)邏輯上限定不能多例只能單例的情況,例如:類似于計(jì)數(shù)器之類的存在,一般都需要使用一個實(shí)例來進(jìn)行記錄,若多例計(jì)數(shù)則會不準(zhǔn)確。
?
?
餓漢式:
條件:
? 優(yōu)缺點(diǎn):
優(yōu)點(diǎn):安全
缺點(diǎn):可能會導(dǎo)致對象創(chuàng)建過早
1 package com.設(shè)計(jì)模式; 2 3 /** 4 * 餓漢式 5 */ 6 public class ObjectShow1 { 7 public static int i = 123; 8 //靜態(tài)私有成員,類在加載初期完成初始化;同時帶來加載過早的問題 9 private static ObjectShow1 objectShow1 = new ObjectShow1(); 10 11 private ObjectShow1() { 12 //私有構(gòu)造函數(shù),只能被列對象初始化 13 System.out.println(i); 14 } 15 16 //使用public對外開放獲取本類對象 17 public static ObjectShow1 getObjectShow1() { 18 return objectShow1; 19 } 20 } View Code?
?
懶漢式:
?????? 條件:
優(yōu)缺點(diǎn):
優(yōu)點(diǎn):對象總是被需要的時候才被創(chuàng)建 解決了可能加載時機(jī)過早的問題
缺點(diǎn):在線程初期 線程不安全
1 package com.設(shè)計(jì)模式; 2 3 /** 4 * 懶漢式 5 */ 6 public class ObjectShow2 { 7 public static int i = 123; 8 //靜態(tài)私有成員,不用構(gòu)造器進(jìn)行初始化 9 private static ObjectShow2 objectShow2 = null; 10 11 private ObjectShow2() { 12 //私有構(gòu)造函數(shù),只能被列對象初始化 13 System.out.println(i); 14 } 15 16 //使用public對外開放獲取本類對象,只有調(diào)用方法才會進(jìn)行初始化 17 public static ObjectShow2 getObjectShow2() { 18 if (objectShow2 == null) { 19 objectShow2 = new ObjectShow2(); 20 } 21 return objectShow2; 22 } 23 } View Code?
?
雙重檢索式:
?????? 條件:
?????? 1.構(gòu)造器私有化
?????? 2.本類的對象作為奔雷的屬性存在 static 修飾 但不進(jìn)行初始化
?????? 3.公共的靜態(tài)方法 并且判斷是否給屬性賦值
優(yōu)缺點(diǎn):
程序的前期 線程不安全
Synchronized 鎖
Synchronized 代碼塊 要求同一時間只有一個線程進(jìn)入代碼塊區(qū)域
因?yàn)閖vm內(nèi)存模型的原因 雙重檢索 也會有微小的可能發(fā)生問題
1 package com.設(shè)計(jì)模式; 2 3 /** 4 * 雙重檢索式 5 */ 6 public class ObjectShow3 { 7 public static int i = 123; 8 //靜態(tài)私有成員,不用構(gòu)造器進(jìn)行初始化 9 private static ObjectShow3 objectShow3; 10 11 private ObjectShow3() { 12 //私有構(gòu)造函數(shù),只能被列對象初始化 13 System.out.println(i); 14 } 15 16 //使用public對外開放獲取本類對象,只有調(diào)用方法才會進(jìn)行初始化 17 public static ObjectShow3 getObjectShow3() { 18 if (objectShow3 == null) { 19 //同步塊,線程安全的創(chuàng)建實(shí)例 20 synchronized (ObjectShow3.class) { 21 //再次檢查實(shí)例是否存在,不在才創(chuàng)建 22 if (objectShow3 == null) 23 objectShow3 = new ObjectShow3(); 24 } 25 } 26 return objectShow3; 27 } 28 } View Code?
?
靜態(tài)內(nèi)部類式:
條件:
?????? 1.定義一個靜態(tài)內(nèi)部類
?????? 2.外部類構(gòu)造器私有化
?????? 3.外部類的對象 作為內(nèi)部類的屬性存在 static 修飾 進(jìn)行初始化
?????? 4.公共的靜態(tài)方法
優(yōu)缺點(diǎn):
解決了,對象創(chuàng)建時機(jī)過早的問題
沒有產(chǎn)生線程安全問題
1 package com.設(shè)計(jì)模式; 2 3 /** 4 * 靜態(tài)內(nèi)部類式 5 */ 6 public class ObjectShow4 { 7 public static int i = 123; 8 9 static class InitObjectShow { 10 private static ObjectShow4 os = new ObjectShow4(); 11 12 public static ObjectShow4 getObj() { 13 return os; 14 } 15 } 16 17 private ObjectShow4() { 18 System.out.println("ObjectShow4.ObjectShow4"); 19 } 20 21 public void show() { 22 System.out.println("ObjectShow4.show"); 23 } 24 } View Code?
轉(zhuǎn)載于:https://www.cnblogs.com/shwang/p/9325666.html
總結(jié)
以上是生活随笔為你收集整理的Java 设计模式-【单例模式】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: UESTC_秋实大哥与快餐店 2015
- 下一篇: 应用jacob组件造成的内存溢出解决方案