Java 23種設計模式 之單例模式 7種實現方式

1、懶漢式(線程不安全)java

package com.java.singleton;

//懶漢式 線程不安全
public class LazySingleton {

    //私有構造方法 只容許在內部進行實例的建立
    private LazySingleton() {
    }


    private static LazySingleton instance = null;

    //建立實例
    public static LazySingleton getInstance() {

        if (instance == null) {
            instance = new LazySingleton();
        }

        return instance;
    }
}

2、懶漢式(線程安全)spring

package com.java.singleton;

//懶漢式 線程安全
public class SynchronizedLazySingleton {

    //私有構造方法 只容許在內部進行實例的建立
    private SynchronizedLazySingleton() {
    }


    private static SynchronizedLazySingleton instance = null;

    //建立實例  線程安全
    public static synchronized SynchronizedLazySingleton getInstance() {

        if (instance == null) {
            instance = new SynchronizedLazySingleton();
        }

        return instance;
    }

}

3、餓漢式(線程安全)緩存

package com.java.singleton;

//餓漢式
public class HungrySingleton {

    //私有構造方法 只容許在內部進行實例的建立
    private HungrySingleton() {
    }

    //靜態初始化 由JVM保證線程安全
    private static HungrySingleton instance = new HungrySingleton();

    //建立實例
    public static HungrySingleton getInstance() {

        return instance;
    }

}

4、緩存實現(線程不安全)安全

package com.java.singleton;

import java.util.HashMap;
import java.util.Map;

//線程不安全 緩存實現
public class CacheSingleton {

    //私有構造方法 只容許在內部進行實例的建立
    private CacheSingleton() {
    }

    //構造緩存容器
    private static Map<String, CacheSingleton> map = new HashMap<>();

    //構造默認的存放key
    private static final String DEFAULT_KEY = "Cache";


    //建立實例
    public static CacheSingleton getInstance() {

        //先從緩存中取 沒有就建立並放入緩存  有就返回
        CacheSingleton instance = (CacheSingleton) map.get(DEFAULT_KEY);

        if (instance == null) {

            instance = new CacheSingleton();
            map.put(DEFAULT_KEY, instance);
        }

        return instance;
    }

}

5、雙重檢查加鎖(懶漢式 線程安全的進一步優化)測試

package com.java.singleton;


//雙重檢查加鎖  懶漢式在方法上加synchronized的進一步優化
public class DoubleCheckedLockingSingleton {

    //私有構造方法 只容許在內部進行實例的建立
    private DoubleCheckedLockingSingleton() {
    }

    //volatile 修飾的變量不會被本地線程緩存 對該變量的讀寫直接做用於共享內存 相似於互斥鎖
    private volatile static DoubleCheckedLockingSingleton instance = null;

    //建立實例
    public static DoubleCheckedLockingSingleton getInstance() {

        if (instance == null) {

            synchronized (DoubleCheckedLockingSingleton.class) {

                if (instance == null) {
                    instance = new DoubleCheckedLockingSingleton();
                }
            }

        }

        return instance;
    }


}

6、 Lazy Initialization Holder Class實現單例優化

package com.java.singleton;


//靜態內部類 Lazy Initialization Holder Class
public class LazyInitializationHolderClassSingleton {

    //私有構造方法 只容許在內部進行實例的建立
    private LazyInitializationHolderClassSingleton() {
    }

    /*
     * 靜態成員式內部類 該內部類的實例對象與外部類的實例無綁定關係
     * 有且只有在LazyInitializationHolder被調用instance時 在會對對象實例進行裝載
     * 從而實現延時加載
     */
    private static class LazyInitializationHolder {

        /*
         * 靜態初始化器 由JVM保證線程安全
         *
         */
        private static LazyInitializationHolderClassSingleton instance = new LazyInitializationHolderClassSingleton();
    }


    //建立實例
    public static LazyInitializationHolderClassSingleton getInstance() {

        return LazyInitializationHolder.instance;
    }


}

7、枚舉實現單例spa

package com.java.singleton;

public enum EnumSingleton {

    //枚舉類的每一個元素 都表明一個單例
    uniqueEnumSingleton;


    public  void method() {

        System.out.println("EnumSingleton"+uniqueEnumSingleton.hashCode());
    }

}

8、測試類線程

package com.java.singleton;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SingletonApplicationTests {

    @Test
    public void testCacheSingleton() {

        for (int i = 0; i < 3; i++) {

            System.out.println("CacheSingleton\t" + CacheSingleton.getInstance());
        }
        System.out.println("-------------------------------------------------------------------\n");
    }

    @Test
    public void testDoubleCheckedLockingSingleton() {

        for (int i = 0; i < 3; i++) {

            System.out.println("DoubleCheckedLockingSingleton\t" + DoubleCheckedLockingSingleton.getInstance());
        }
        System.out.println("-------------------------------------------------------------------\n");
    }

    @Test
    public void testEnumSingleton() {

        for (int i = 0; i < 3; i++) {

            EnumSingleton.uniqueEnumSingleton.method();
        }
        System.out.println("-------------------------------------------------------------------\n");
    }


    @Test
    public void testHungrySingleton() {

        for (int i = 0; i < 3; i++) {

            System.out.println("HungrySingleton\t" + HungrySingleton.getInstance());
        }
        System.out.println("-------------------------------------------------------------------\n");
    }


    @Test
    public void testLazyInitializationHolderClassSingleton() {

        for (int i = 0; i < 3; i++) {

            System.out.println("LazyInitializationHolderClassSingleton\t" + LazyInitializationHolderClassSingleton.getInstance());
        }
        System.out.println("-------------------------------------------------------------------\n");
    }

    @Test
    public void testLazySingleton() {

        for (int i = 0; i < 3; i++) {

            System.out.println("LazySingleton\t" + LazySingleton.getInstance());
        }
        System.out.println("-------------------------------------------------------------------\n");
    }


    @Test
    public void testSynchronizedLazySingleton() {

        for (int i = 0; i < 3; i++) {

            System.out.println("SynchronizedLazySingleton\t" + SynchronizedLazySingleton.getInstance());
        }
        System.out.println("-------------------------------------------------------------------\n");
    }


}

9、測試結果
圖片描述code

相關文章
相關標籤/搜索