1. 程式人生 > 其它 >Java設計模式(一)單例模式

Java設計模式(一)單例模式

一、單例模式概述

1、基本介紹

  • 單例模式(Singleton Pattern)是 Java 中最簡單的設計模式之一。這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。這種模式涉及到一個單一的類,該類負責建立自己的物件,同時確保只有單個物件被建立。這個類提供了一種訪問其唯一的物件的方式,可以直接訪問,不需要例項化該類的物件。在整個程式的執行過程中,所有該類的引用都指向同一個例項。

  • 特點:

    1. 整個程式執行過程中只有一個例項。

    2. 類必須在內部建立自己的例項。

    3. 該類必須提供一個公共方法供其它類獲取這個例項。

  • 好處:

    1. 防止一個類被頻繁的建立和銷燬,降低了系統的資源消耗,因為只有一個例項。

    2. 避免對資源的多重佔用。

2、應用場景

  • 要求生產唯一序列號。

  • WEB 中的計數器,不用每次重新整理都在資料庫里加一次,用單例先快取起來。

  • 建立的一個物件需要消耗的資源過多,比如 I/O 與資料庫的連線等。

二 、單例模式的七種實現

1、餓漢式-靜態常量

class Singleton{
//1.構造器私有化
private Singleton(){
}

//2.本類內部宣告物件並初始化
private final static Singleton instance = new Singleton();

//3.對外提供一個公有的靜態方法,返回例項物件
public static Singleton getInstance(){
return instance;
}
}
  • 餓漢式-靜態常量

    1. 構造器私有;

    2. 內部宣告靜態常量並初始化;

    3. 提供public方法獲取例項。

  • 優點:

    1. 寫法簡單;

    2. 類載入時完成例項化,執行緒安全。

  • 缺點:

    1. 沒有實現懶載入,如果沒有用到該類,則會造成資源浪費。

2、餓漢式-靜態程式碼塊

class Singleton{
//1.構造器私有化
private Singleton(){
}

//2.本類內部宣告物件
private static Singleton instance;

static {
//靜態程式碼塊中物件例項化
instance = new Singleton();
}

//3.對外提供一個公有的靜態方法,返回例項物件
public static Singleton getInstance(){
return instance;
}
}
  • 餓漢式-靜態程式碼塊

    1. 構造器私有;

    2. 內部宣告靜態常量;

    3. 通過靜態程式碼塊初始化

    4. 提供public方法獲取例項。

  • 優點:

    1. 寫法簡單;

    2. 類載入時完成例項化,執行緒安全。

  • 缺點:

    1. 沒有實現懶載入,如果沒有用到該類,則會造成資源浪費。

3、懶漢式-執行緒不安全

class Singleton{

//1.構造器私有化
private Singleton(){
}

//2.本類內部宣告物件
private static Singleton instance;

//3.對外提供一個公有的靜態方法,第一次使用時例項化物件
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
  • 懶漢式-執行緒不安全

    1. 構造器私有;

    2. 內部建立靜態常量;

    3. 第一次使用時例項化物件。

  • 優點:

    1. 使用時載入,避免資源浪費,只能在單執行緒使用。

  • 缺點:

    1. 如果多個執行緒同時進入if判空,則有可能建立多個例項,執行緒不安全。

4、懶漢式-同步關鍵字(執行緒安全)

class Singleton{

//1.構造器私有化
private Singleton(){
}

//2.本類內部宣告物件
private static Singleton instance;

//3.對外提供一個公有的靜態方法,第一次使用時例項化物件,並加入同步關鍵字
synchronized public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
  • 懶漢式-同步關鍵字(執行緒安全)

    1. 構造器私有;

    2. 內部宣告靜態常量;

    3. 第一次訪問例項化物件;

    4. 加入synchronized同步關鍵字,每次只有一個執行緒能進入該方法。

  • 優點:

    1. 執行緒安全;

    2. 懶載入。

  • 缺點:

    1. 效率太低,每次呼叫getInstance要進行同步,不推薦使用。

5、懶漢式-雙重檢查(執行緒安全)

class Singleton{

//1.構造器私有化
private Singleton(){
}

//2.本類內部宣告物件,使用volatile修改其他執行緒可立即感知並且防止程式碼重排序
private static volatile Singleton instance;

//3.對外提供一個公有的靜態方法,第一次使用時例項化物件,並加入同步程式碼塊雙重檢查
public static Singleton getInstance(){
if(instance == null){
{
synchronized (Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
}
return instance;
}
}
  • 懶漢式-雙重檢查

    1. 構造器私有;

    2. 內部宣告靜態常量並標識volatile關鍵字;

    3. 第一次訪問進行物件例項化,並使用雙重檢查機制。

  • 優點:

    1. 懶載入;

    2. 執行緒安全,除了剛開始多個執行緒可能需要進行同步,後面都不需要進入同步程式碼塊,效率高,推薦使用。

  • 缺點:

    1. 無。

6、靜態內部類

class Singleton{

//1.構造器私有化
private Singleton(){
}

//2靜態內部類
private static class SingletonInstance{
private static final Singleton INSTANCE = new Singleton();
}

//3.公共方法獲取例項
public static Singleton getInstance(){
return SingletonInstance.INSTANCE;
}

}
  • 靜態內部類

    1. 構造器私有;

    2. 提供靜態類;

    3. 提供公共靜態方法返回物件例項。

  • 優點:

    1. JVM在載入外部類時並不會載入內部類,只有顯示呼叫getInstance才會對內部類進行載入,所以提供了懶載入的效果。

    2. 執行緒安全,JVM載入類時是單執行緒的。

  • 缺點:

    1. 無。

7、列舉

enum Singleton{
//屬性
INSTANCE;
}
//獲取物件
//Singleton instance = Singleton.INSTANCE;
  • 列舉

    1. 建立列舉類;

    2. 提供屬性。

  • 優點:

    1. 實現簡單;

    2. 多執行緒安全;

    3. 防止反序列化重新建立物件;

    4. 這種方式是 Effective Java 作者 Josh Bloch 提倡的方式。

  • 缺點:

    1. 無。

三、JDK實現單例模式

  • java.lang包下Runtime類

  • 使用了第一種餓漢式