文章出處
文章列表
一、Java中的單例:
特點:
① 單例類只有一個實例
② 單例類必須自己創建自己唯一實例
③ 單例類必須給所有其他對象提供這一實例
二、兩種模式:
①懶漢式單例<線程不安全>
在類加載時,不創建實例,運行調用時創建。類加載快,在運行時獲取對象速度慢
示例:
public class Singleton { private static Singleton uniqueInstance = null; private Singleton() { } public static Singleton getInstance() { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } return uniqueInstance; }
②餓漢式單例<線程安全>
在類加載的時候,就完成初始化。所以類加載慢,但是在運行時獲取對象快
示例:
//餓漢式單例類.在類初始化時,已經自行實例化 public class Singleton1 { //私有的默認構造子 private Singleton1() {} //已經自行實例化 private static final Singleton1 single = new Singleton1(); //靜態工廠方法 public static Singleton1 getInstance() { return single; } }
三、如何保證多線程下的單例:
① 同步鎖<主要是通過使用synchronized來加互斥鎖進行同步控制。>
public class LazySingleton { private static LazySingleton instance = null; private LazySingleton(){} public static synchronized LazySingleton getInstance(){ if(instance == null){ instance = new LazySingleton(); } return instance; } }
②雙重校驗鎖
所謂“雙重檢查加鎖”機制,指的是:并不是每次進入getInstance方法都需要同步,而是先不同步,進入方法后,先檢查實例是否存在,如果不存在才進行下面的同步塊,這是第一重檢查,進入同步塊過后,再次檢查實例是否存在,如果不存在,就在同步的情況下創建一個實例,這是第二重檢查。這樣一來,就只需要同步一次了,從而減少了多次在同步情況下進行判斷所浪費的時間。
“雙重檢查加鎖”機制的實現會使用關鍵字volatile,它的意思是:被volatile修飾的變量的值,將不會被本地線程緩存,所有對該變量的讀寫都是直接操作共享內存,從而確保多個線程能正確的處理該變量。
private volatile static Singleton instance = null; private Singleton(){} public static Singleton getInstance(){ //先檢查實例是否存在,如果不存在才進入下面的同步塊 if(instance == null){ //同步塊,線程安全的創建實例 synchronized (Singleton.class) { //再次檢查實例是否存在,如果不存在才真正的創建實例 if(instance == null){ instance = new Singleton(); } } } return instance; } }
文章列表
全站熱搜