欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

设计模式—单例模式

程序员文章站 2023-12-28 13:24:10
...

单例模式

核心作用

保证一个类只有一个实例,并且 提供一个访问该实例的全局访问点

优点

  • 由于单例模式只生成一个实例,减少了系统性能开销
  • 单例模式可以在系统设置全局的访问点,优化共享资源访问

常见的五种单例模式实现方式

  • 饿汉式:(线程安全,调用效率高,不能延时加载)
  • 懒汉式:(线程安全,调用效率不高,可以延时加载)
  • DCL懒汉式:(由于JVM底层内部模型原因,偶尔会出现问题,不建议使用)
  • 饿汉式改进:静态内部类式(线程安全,调用效率高,可以延时加载)
  • 枚举单例:(线程安全,调用效率高,不能延时加载)

饿汉式

/**
 * 饿汉式单例
 */
public class SingletonDemo01 {
    // 私有化构造器
    private SingletonDemo01(){
    }
    // 类初始化时就加载该对象
    private static SingletonDemo01 instance = new SingletonDemo01();
    // 提供获取该对象的方法,没有synchronized,效率高
    public static SingletonDemo01 getInstance(){
        return instance;
    }
}

class SingletonDemo01Test{
    public static void main(String[] args) {
        SingletonDemo01 instance1 = SingletonDemo01.getInstance();
        SingletonDemo01 instance2 = SingletonDemo01.getInstance();
        System.out.println(instance1 == instance2);  // true
    }
}

懒汉式

/**
 * 懒汉式
 */
public class SingletonDemo02 {
    // 私有化构造器
    private SingletonDemo02(){
    }
    // 类初始化时不加载该对象
    private static SingletonDemo02 instance;
    // 提供获取该对象的方法,有synchronized,效率较低
    public static synchronized SingletonDemo02 getInstance(){
        if(instance == null){
            instance = new SingletonDemo02();
        }
        return instance;
    }
}

class SingletonDemo02Test{
    public static void main(String[] args) {
        SingletonDemo02 instance1 = SingletonDemo02.getInstance();
        SingletonDemo02 instance2 = SingletonDemo02.getInstance();
        System.out.println(instance1 == instance2);  // true
    }
}

DCL懒汉式

/**
 * DCL懒汉式
 */
public class SingletonDemo03 {
    // 私有化构造器
    private SingletonDemo03(){
    }
    // 类初始化时不加载该对象
    private volatile static SingletonDemo03 instance;
    // 提供获取该对象的方法,有synchronized,效率较低
    public static SingletonDemo03 getInstance(){
        if(instance == null){
            synchronized (SingletonDemo03.class){
                if(instance == null){
                    instance = new SingletonDemo03();
                }
            }
        }
        return instance;
    }
}

class SingletonDemo03Test{
    public static void main(String[] args) {
        SingletonDemo03 instance1 = SingletonDemo03.getInstance();
        SingletonDemo03 instance2 = SingletonDemo03.getInstance();
        System.out.println(instance1 == instance2);  // true
    }
}

饿汉式改进

/**
 * 饿汉式改进,静态内部类实现
 */
public class SingletonDemo04 {
    private SingletonDemo04(){
    }
    private static class InnerClass{
        private static final SingletonDemo04 instance = new SingletonDemo04();
    }
    public static SingletonDemo04 getInstance(){
        return InnerClass.instance;
    }
}

class SingletonDemo04Test{
    public static void main(String[] args) {
        SingletonDemo04 instance1 = SingletonDemo04.getInstance();
        SingletonDemo04 instance2 = SingletonDemo04.getInstance();
        System.out.println(instance1 == instance2);  // true
    }
}

反射机制可以破坏该单例

class SingletonDemo04Test{
    public static void main(String[] args) throws Exception {
        SingletonDemo04 instance1 = SingletonDemo04.getInstance();
        Constructor<SingletonDemo04> declaredConstructor = SingletonDemo04.class.getDeclaredConstructor(null);
        declaredConstructor.setAccessible(true);
        SingletonDemo04 instance2 = declaredConstructor.newInstance();
        System.out.println(instance1 == instance2); // false
        System.out.println(instance1.hashCode());
        System.out.println(instance2.hashCode());
    }
}

枚举单例

/**
 * 枚举单例
 */
public enum SingletonDemo05 {
    INSTANCE;
    public SingletonDemo05 getInstance(){
        return INSTANCE;
    }
}

class SingletonDemo05Test{
    public static void main(String[] args) {
        SingletonDemo05 instance1 = SingletonDemo05.INSTANCE;
        SingletonDemo05 instance2 = SingletonDemo05.INSTANCE;
        System.out.println(instance1 == instance2); //true
    }
}
相关标签: 踩坑日记

上一篇:

下一篇: