程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> 設計模式 單件-Singleton

設計模式 單件-Singleton

編輯:JAVA編程入門知識

單件模式 Singleton

什麼時候使用?當需要獨一無二的對象時,請想起他。

舉例:線程池(threadpool),緩存(cache),對話框,處理偏好設置和注冊表(registry)的對象,驅動程序對象。

無需具體例子,先看類圖:包含一個private的自己的實例。private的構造函數,確保無法在類以外創建。在getInstance()中檢測私有實例是否創建,未則創建,若已存在則直接返回。

看代碼更好理解記憶。

經典實現方式 Typical Singleton

public class Singleton {
  private static Singleton uniqueInstance;
  private Singleton() {}
  public static Singleton getInstance {
    if (uniqueInstance == null) {
      uniqueInstance  = new Singleton();
    }        
    return uniqueInstance;
 }            
}

 

經典實現看似完美,但存在問題。它不是線程安全的。當兩個線程同時調用的時候,有可能同時進入 uniqueInstance == null 的if塊中。這樣對象就不是唯一了。後進入的線程會獲得一個新的instance。解決方法,馬上直觀想到,使用synchronized確保線程安全。 

 

Singleton Lazy Initialized (延遲加載)

public class Singleton {
  private static Singleton uniqueInstance;
  private Singleton() {}
  public static synchronized Singleton getInstance {
    if (uniqueInstance == null) {
      uniqueInstance  = new Singleton();
    }        
    return uniqueInstance;
 }            
}

 

如果對性能要求非常高,以上synchronized確實每次都要判斷有性能擔憂。可以改進如下。

 

Singleton Eagerly Initialized (急切創建)

public class Singleton {
  private static Singleton uniqueInstance = new Singleton();
  private Singleton() {}
  public static synchronized Singleton getInstance {
    return uniqueInstance;
 }            
}

 

很好的解決問題了。以上利用了JVM加載機制。在加載類的時候就吧實例創建好。除此,還有一種方法。

 

Singleton Double-checked Locking (雙重檢查鎖)

public class Singleton {
  private volatile static Singleton uniqueInstance;
  private Singleton() {}
  public static Singleton getInstance {
    if (uniqueInstance == null) {
      synchronized (Singleton.class) {
          if (uniqueInstance == null) {  
             uniqueInstance  = new Singleton();
          }
      }
    }        
    return uniqueInstance;
 }            
}

以上使用了volatile關鍵字,使uniqueInstance是線程同步讀的。即線程總能讀到最新的值。uniqueInstance為null時才進行創建。使用synchrinized確保線程安全。同時在塊內再次檢測是否需要創建。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved