设计模式:单例模式

·  阅读 238

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

适⽤场景: 单例模式只允许创建⼀个对象,因此节省内存,加快对象访问速度,因此对象需要被公⽤的场 合适合使⽤,如多个模块使⽤同⼀个数据源连接对象等等。如:

  1. 需要频繁实例化然后销毁的对象。
  2. 创建对象时耗时过多或者耗资源过多,但⼜经常⽤到的对象。
  3. 有状态的⼯具类对象。
  4. 频繁访问数据库或⽂件的对象。

一、饿汉式

/**
 * @author GodLiang
 * @version 1.0
 * @date 2021/2/9 17:12
 * @description: TODO  单例模式  饿汉式
 */
public class HungrySingleton {
    //在类加载时创建对象。且一直不会被回收
    private static HungrySingleton hungrySingleton = new HungrySingleton();

    //防⽌反射获取多个对象的漏洞
    private HungrySingleton() {
        if (null != hungrySingleton)
            throw new RuntimeException();
    }

    public static HungrySingleton getSingletonBean() {
        return hungrySingleton;
    }
}

复制代码

饿汉式优缺点

优点: 没有加锁,执行效率会提高。

缺点: 类加载时就初始化,浪费内存。

二、懒汉式

双重校验锁:

/**
 * @author GodLiang
 * @version 1.0
 * @date 2021/2/9 17:17
 * @description: TODO 单例模式 懒汉式
 */
public class LazySingleton {

    //加volatile 实现可见性。其他线程创建好对象后马上同步到其他线程,并禁止指令重排
    private volatile static LazySingleton lazySingleton;
    
    private LazySingleton() {
        //禁止反射创建对象
        if (null != lazySingleton) {
            throw new RuntimeException("禁止反射");
        }
        System.out.println("c初始化");
    }

    public static LazySingleton getLazySingleton() {
        //这里的是为了避免每次进来都加锁。如果不为空则创建过了,不需要加锁。解决效率问题
        if (null == lazySingleton) {
            synchronized (LazySingleton.class) {
                //进来再判断一次。防止堵塞在锁处。多次创建示例
                if (null == lazySingleton) {
                    lazySingleton = new LazySingleton();
                }
            }
        }
        return lazySingleton;
    }

    public static void main(String[] args) throws IllegalAccessException, InstantiationException, InterruptedException {
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                LazySingleton singletonBean = LazySingleton.getLazySingleton();
            }).start();
        }
        LazySingleton.class.newInstance();
    }
}

复制代码

优缺点

  1. 优点: 第一次调用才初始化,避免内存浪费。
  2. 缺点: 必须加锁 synchronized和volatile 才能保证单例,但加锁会影响效率。

其他懒汉略。。。

分类:
后端
标签: