您現在的位置是:首頁 > 手機遊戲首頁手機遊戲
單例模式第一版
- 2022-04-11
什麼是單件模式
設計模式系列
特徵
構造方法私有化
靜態成員物件
獲取單例物件的方法
分類
懶漢模式(執行緒不安全)
餓漢模式(執行緒安全)
程式碼實現
懶漢模式:
public class Singleton { private Singleton() {} //私有建構函式 private static Singleton instance = null; //單例物件 //靜態工廠方法 public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; }}
餓漢模式:
public class Singleton { private Singleton() {} //私有建構函式 private static Singleton instance = new Singleton(); //單例物件 //靜態工廠方法 public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; }}
問題分析
為什麼說懶漢模式是執行緒不安全呢?假設有A、B兩個同時訪問,此時 instance 物件還沒有構建,初始化值為null。A、B兩個執行緒都訪問到了 if(instance == null)這個判斷條件,都執行了instance = new Singleton();所以instance被構建了兩次。
基於原來的程式碼修改如下:
public class Singleton { private Singleton() {} //私有建構函式 private volatile static Singleton instance = null; //單例物件 //靜態工廠方法 public static Singleton getInstance() { if (instance == null) { //雙重檢測機制 synchronized (Singleton。class){ //同步鎖 if (instance == null) { //雙重檢測機制 instance = new Singleton(); } } } return instance; }}
此修改也叫作“
雙重檢測
”是單例的一種實現方式之一,還有其它的實現方式,小夥伴不妨想一想。
但是以上修改的程式碼還存在隱藏的漏洞就是JVM編譯器的
指令重排
會導致在多執行緒情況下,有的執行緒會獲取到
沒有初始化完成的instance物件
。對應的修改如下:
如何避免這一情況呢?我們需要在instance物件前面增加一個修飾符
volatile。
public class Singleton { private Singleton() {} //私有建構函式 private static Singleton instance = null; //單例物件 //靜態工廠方法 public static Singleton getInstance() { if (instance == null) { //雙重檢測機制 synchronized (Singleton。class){ //同步鎖 if (instance == null) { //雙重檢測機制 instance = new Singleton(); } } } return instance; }}
以上就是我們單例第一版的內容了,有興趣的小夥伴也可以去了解一下
volatile