Java 23种设计模式 之单例模式 7种实现方式
一、懒汉式(线程不安全)
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;
    }
}
二、懒汉式(线程安全)
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;
    }
}
三、饿汉式(线程安全)
package com.java.singleton;
//饿汉式
public class HungrySingleton {
    //私有构造方法 只允许在内部进行实例的创建
    private HungrySingleton() {
    }
    //静态初始化 由JVM保证线程安全
    private static HungrySingleton instance = new HungrySingleton();
    //创建实例
    public static HungrySingleton getInstance() {
        return instance;
    }
}
四、缓存实现(线程不安全)
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;
    }
}
五、双重检查加锁(懒汉式 线程安全的进一步优化)
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;
    }
}
六、 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;
    }
}
七、枚举实现单例
package com.java.singleton;
public enum EnumSingleton {
    //枚举类的每个元素 都代表一个单例
    uniqueEnumSingleton;
    public  void method() {
        System.out.println("EnumSingleton"+uniqueEnumSingleton.hashCode());
    }
}
八、测试类
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");
    }
}
九、测试结果

    MY HEART WILL BE FOREVER YOURS UTIL THE DAY I SEE YOU AGAIN

                
            
        
浙公网安备 33010602011771号