1. 程式人生 > >寫一下單例模式,考慮執行緒安全與執行緒不安全的情況

寫一下單例模式,考慮執行緒安全與執行緒不安全的情況

凡是提到設計模式,面試官很喜歡問最簡單的單例模式。

方法一

單例模式最簡單的寫法如下

public class SingletonPatternA {

    private static SingletonPatternA instance = null;

    private SingletonPatternA(){}

    public static SingletonPatternA getInstance(){
        if(instance == null)
            instance = new SingletonPatternA();

        return
instance; } }

這個寫法是餓漢單例模式,但也是是屬於執行緒不安全的寫法。如果多執行緒同時來進行getInstance的操作,那麼這個時候進入if(instance == null)判斷時就需要加入執行緒同步的方法了。

方法二

下面寫一寫存線上程安全的單例模式。

/**
 * 單例模式 - 懶漢、執行緒安全
 */
public class SingletonPatternB {

    private static SingletonPatternB instance;

    private SingletonPatternB() {
    }

    // 加入synchronized,把整個方法序列執行 
public static synchronized SingletonPatternB getInstance(){ if(instance == null){ instance = new SingletonPatternB(); } return instance; } }

這個方法可以保證執行緒的同步,但是效率太低,因為大多數情況下不需要同步

方法三

上述兩種方法都是懶漢單例模式,但是處理執行緒同步還是存有一些問題,所以參考了多種執行緒安全的單例模式後,我覺得下面這種比較好理解。

/**
 * enum 是JDK1.5後出來的
 */
public enum SingletonPatternC {
    INSTANCE;
    public void PrintFunction(){
        System.out.println("This is Enum Type");
    };

    public static void main(String[] args) {
        SingletonPatternC ins = SingletonPatternC.INSTANCE;
        ins.PrintFunction();
    }
}

-------
This is Enum Type

這種方式是Effective Java作者Josh Bloch 提倡的方式,它不僅能避免多執行緒同步問題,而且還能防止反序列化重新建立新的物件,可謂是很堅強的壁壘啊。1

方法四

餓漢式單例模式,本身是一種執行緒安全的方法,再類建立的時候,物件就生成了,所以不存線上程同步的問題。2

/**
 * 餓漢式單例模式
 */
public class SingletonPatternD {
    private static SingletonPatternD instance = new SingletonPatternD();

    private SingletonPatternD(){
    }

    public SingletonPatternD getInstance(){
        return instance;
    }
}