1. 程式人生 > 其它 >設計模式-23種設計模式-建立型-單例模式

設計模式-23種設計模式-建立型-單例模式

一、單例模式介紹

二、單例模式引入

1. 餓漢式(靜態常量)---可用,不推薦

程式碼實現(Java)

public class SingletonTest01 {
    public static void main(String[] args) {
        //測試
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2); //
true System.out.println("instance1.hashCode=" + instance1.hashCode()); System.out.println("instance2.hashCode=" + instance2.hashCode()); } } //餓漢式(靜態變數) class Singleton { //1.構造器私有化 private Singleton() { } //2.本類內部建立物件例項 private final static Singleton instance = new
Singleton(); //3.提供一個公有的靜態方法,返回例項物件 public static Singleton getInstance(){ return instance; } }

2. 餓漢式(靜態程式碼塊)---可用,不推薦

程式碼實現(Java)

public class SingletonTest02 {
    public static void main(String[] args) {
        //測試
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 
= Singleton.getInstance(); System.out.println(instance1 == instance2); //true System.out.println("instance1.hashCode=" + instance1.hashCode()); System.out.println("instance2.hashCode=" + instance2.hashCode()); } } //餓漢式(靜態程式碼塊) class Singleton { //1.構造器私有化 private Singleton() { } //2.本類內部建立物件例項 private static Singleton instance; static { //在靜態程式碼塊中,建立單例物件 instance = new Singleton(); } //3.提供一個公有的靜態方法,返回例項物件 public static Singleton getInstance(){ return instance; } }

3. 懶漢式(執行緒不安全)---不推薦

程式碼實現(Java)

public class SingletonTest03 {
    public static void main(String[] args) {
        //測試
        System.out.println("懶漢式1,執行緒不安全~");
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2); //true
        System.out.println("instance1.hashCode=" + instance1.hashCode());
        System.out.println("instance2.hashCode=" + instance2.hashCode());

    }
}


class Singleton{
    private static Singleton instance;

    private Singleton() {}

    //提供一個靜態的公有方法,當使用到該方法時,才去建立instance
    //即懶漢式
    public static Singleton getInstance(){
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}

4. 懶漢式(執行緒安全,同步方法)---不推薦

程式碼實現(Java)

public class SingletonTest04 {
    public static void main(String[] args) {
        //測試
        System.out.println("懶漢式2,執行緒安全~");
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2); //true
        System.out.println("instance1.hashCode=" + instance1.hashCode());
        System.out.println("instance2.hashCode=" + instance2.hashCode());

    }
}

//懶漢式(執行緒安全,同步方法)
class Singleton{
    private static Singleton instance;

    private Singleton() {}

    //提供一個靜態的公有方法,加入同步處理的程式碼,解決了執行緒安全問題
    //即懶漢式
    public static synchronized Singleton getInstance(){
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}

5. 懶漢式(執行緒安全,同步程式碼塊)---不推薦

程式碼實現(Java)

public class SingletonTest05 {
    public static void main(String[] args) {
        System.out.println("懶漢式3,執行緒不安全~");
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2); //true
        System.out.println("instance1.hashCode=" + instance1.hashCode());
        System.out.println("instance2.hashCode=" + instance2.hashCode());

    }
}

//懶漢式(執行緒不安全,同步程式碼塊)
class Singleton{
    private static Singleton instance;

    private Singleton() {}

    //提供一個靜態的公有方法,加入同步處理的程式碼塊,並沒有解決執行緒安全問題
    //即懶漢式
    public static Singleton getInstance(){
        if(instance == null){
            synchronized (Singleton.class){
                instance = new Singleton();
            }
        }
        return instance;
    }
}

6. 雙重檢查---推薦

程式碼實現(Java)

public class SingletonTest06 {
    public static void main(String[] args) {
        System.out.println("雙重檢查,執行緒安全~");
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2); //true
        System.out.println("instance1.hashCode=" + instance1.hashCode());
        System.out.println("instance2.hashCode=" + instance2.hashCode());

    }
}

//雙重檢查
class Singleton{
    private static volatile Singleton instance;

    private Singleton() {}

    //提供一個靜態的公有方法,加入雙重檢查程式碼,解決執行緒安全問題,同時解決懶漢載入問題
    //同時保證了效率,推薦使用
    public static Singleton getInstance(){
        if(instance == null){
            synchronized (Singleton.class){
                if(instance == null){
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

7. 靜態內部類---推薦

程式碼實現(Java)

public class SingletonTest07 {
    public static void main(String[] args) {
        System.out.println("使用靜態內部類完成單例模式,執行緒安全~");
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2); //true
        System.out.println("instance1.hashCode=" + instance1.hashCode());
        System.out.println("instance2.hashCode=" + instance2.hashCode());

    }
}

//靜態內部類完成,推薦使用
class Singleton{
    private static volatile Singleton instance;

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

    //靜態內部類,該類中有一個靜態屬性 Singleton
    private static class SingletonInstance{
        private static final Singleton INSTANCE = new Singleton();
    }

    //提供一個靜態的公有方法,直接返回SingletonInstance.INSTANCE
    public static Singleton getInstance(){
        return SingletonInstance.INSTANCE;
    }
}

8. 列舉---推薦

程式碼實現(Java)

public class SingletonTest08 {
    public static void main(String[] args) {
        Singleton instance = Singleton.INSTANCE;
        Singleton instance1 = Singleton.INSTANCE;
        System.out.println(instance==instance1);

        System.out.println(instance.hashCode());
        System.out.println(instance1.hashCode());

        instance.sayOK();
    }
}

//使用列舉,可以實現單例,推薦使用
enum Singleton {
    INSTANCE; //屬性
    public void sayOK() {
        System.out.println("ok~");
    }
}

三、單例模式在JDK 應用的原始碼分析

三、單例模式注意事項和細節