標籤:共用變數 方式 ext 使用 構造 detail 懶漢 rgb tracking
轉載請註明出處:jiq?欽‘stechnical Blog
1、餓漢式
public class Singleton { private final static Singleton INSTANCE = new Singleton(); private Singleton() { } public static Singleton getInstance() { return INSTANCE; }} 缺點:類載入時即分配空間。若不使用則較為佔用記憶體空間。
2、懶漢式2.1普通加鎖模式
public class Singleton { private static Singleton instance = null; private Singleton() { } public static synchronized Singleton getInstance() { if(instance == null) { instance = new Singleton(); } return instance; }} 缺點:每一個線程調用getInstance都要加鎖,效率低,我們想要僅僅在第一次調用getInstance時加鎖。請看以下的雙重檢測方案
2.2預留位置模式(推薦)
屬於懶漢式單例,由於Java機制規定。內部類SingletonHolder僅僅有在getInstance()方法第一次調用的時候才會被載入(實現了lazy),並且其載入過程是安全執行緒的。內部類載入的時候執行個體化一次instance。
public class Singleton { private Singleton() { } privatestatic class SingletonHolder { //內部類。第一次使用時才載入,且僅僅能SingletonHolder類能訪問//特別注意:static域中改動共用變數是安全執行緒的,由JVM保障 static Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.INSTANCE; }}
2.3雙重檢測
普通雙重檢測:
public class Singleton { private static Singleton instance = null; private Singleton() { } public static Singleton getInstance() { if(instance == null) { synchronzied(Singleton.class) { if(instance == null) { instance = new Singleton(); } } } return instance; }}缺點:指令重排問題,參考我的這篇文章。
解決方式:
針對instance執行個體變數用volatile修飾就能夠了,volatile修飾的話就能夠確保instance = new Singleton();相應的指令不會重排序:
public class Singleton { private static volatile Singletoninstance = null; //以volatilekeyword修飾防止指令重排 private Singleton() { } //建構函式為私人,防止被執行個體化 public static Singleton getInstance() { if(instance == null) { //雙重檢測 synchronzied(Singleton.class) { if(instance == null) { instance = new Singleton(); } } } return instance; }}
Java並發:安全執行緒的單例模式