文章出處

一、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; 

   }
}

 

 

 

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()