1. 程式人生 > 實用技巧 >Sorting Non-numeric Data in R & Python

Sorting Non-numeric Data in R & Python

單例模式(Singleton Pattern)是 Java 中最簡單的設計模式之一。這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。

這種模式涉及到一個單一的類,該類負責建立自己的物件,同時確保只有單個物件被建立。這個類提供了一種訪問其唯一的物件的方式,可以直接訪問,不需要例項化該類的物件。

注意:

  • 1、單例類只能有一個例項。
  • 2、單例類必須自己建立自己的唯一例項。
  • 3、單例類必須給所有其他物件提供這一例項。

下面介紹實現單例的兩種方式:懶漢式、餓漢式。

/**
 * 懶漢式單例模式
 * 懶載入,必須加鎖 synchronized 才能保證單例
 */
public class Singleton {

    public static Singleton instance;

    private Singleton() {

    }

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
/**
 * 餓漢式單例模式
 * 沒有加鎖,執行效率會提高。
 * 類載入時建立物件,消耗記憶體
 */
public class Singleton {

    public static Singleton instance = new Singleton();

    private Singleton() {

    }

    public static Singleton getInstance() {
        return instance;
    }
}

兩種方式都是將構造器 private,防止外界通過 new 來建立例項。

並通過 public static 返回一個例項。

單例模式下如何保證執行緒安全!

通常情況下,一個單例模式是不會出問題的,但是如果在多執行緒的情況下,有可能會生成多個物件。

public class Singleton {

    private Singleton() {

    }

    private static final Singleton instance = null;

    public Singleton getInstance() {
        return new Singleton();
    }
}

如果在多執行緒的情況下,instance 是一個共享資源,如果不進行任何保護機制的話,兩個執行緒有可能同時進入臨界區,這樣這個系統會有超過一個的 Singleton 物件,單例也就失效了。想要保證在多執行緒下依然有用的話,就需要設定鎖機制。

單例模式,執行緒安全的兩種實現

一、雙重校驗鎖( double-checked locking )

/**
 * 雙重校驗鎖
 */
public class Singleton {

    /* 保證 instance 在所有執行緒中同步 */
    public static volatile Singleton instance;

    /* private 避免類在外部被例項化 */
    private Singleton() {

    }

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

分析

  • 第一次判斷 instance 是否為null

    第一次判斷實在 Synchronized 同步程式碼塊前面判斷的,由於單例模式只會建立一個例項,並通過 getInstance() 方法返回物件。所以第一次判斷的原因是為了在 Singleton 物件已經被建立的情況下,避免進入同步程式碼塊,提升效率。

  • 第二次判斷 instance 是否為null

    1、假設:執行緒A已經經過第一次判斷,判斷 instance 為null,並準備進入 synchronized 程式碼塊。

    2、此時執行緒B獲取時間片,由於執行緒A還沒有建立例項,所以 instance == null,這時候執行緒B建立了例項。

    3、此時執行緒A再次獲取時間片,由於剛才經過 instance == null,進入同步程式碼塊。這個時候如果不再次進行 判斷,執行緒A又會再次建立一個例項。這樣就不滿足單例模式的要求,所以第二次判斷很有必要!

二、靜態內部類

/**
 * 靜態內部類單例
 */
public class Singleton {

    private Singleton() {

    }

    public static class SingletonHolder {
        private static final Singleton singleton = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonHolder.singleton;
    }
}

Java中靜態內部類可以訪問其外部類的靜態成員屬性,同時,靜態內部類只有當被呼叫的時候才開始首次被載入,利用了classloader的機制來保證初始化instance時只有一個執行緒,所以也是執行緒安全的,同時沒有效能損耗(加 synchronized 同步鎖),這種實現更推薦。