设计模式--单例模式

    技术2022-07-10  104

    简介

    创建型模式,这种模式只涉及一个单独的类,它负责创建自己的对象,该类也确保只创建单个对象。

    特点 类构造器私有 持有自己类型的属性 对外提供获取实例的静态方法

    分类

    常用分类有五种: 1、懒汉式 懒汉式,顾名思义就是实例在用到的时候才去创建,“比较懒”,用的时候才去检查有没有实例,如果有则返回,没有则新建。有线程安全和线程不安全两种写法,区别就是synchronized关键字。 2、饿汉式 饿汉式,从名字上也很好理解,就是“比较勤”,实例在初始化的时候就已经建好了,不管你有没有用到,都先建好了再说。好处是没有线程安全的问题,坏处是浪费内存空间。 3、双检锁 双检锁,又叫双重校验锁,综合了懒汉式和饿汉式两者的优缺点整合而成。看上面代码实现中,特点是在synchronized关键字内外都加了一层 if 条件判断,这样既保证了线程安全,又比直接上锁提高了执行效率,还节省了内存空间。 4、静态内部类 静态内部类的方式效果类似双检锁,但实现更简单。但这种方式只适用于静态域的情况,双检锁方式可在实例域需要延迟初始化时使用。 5、枚举 枚举的方式是比较少见的一种实现方式,但是看上面的代码实现,却更简洁清晰。并且她还自动支持序列化机制,绝对防止多次实例化。

    简单示例

    public class LazySingleton { private static LazySingleton lazySingleton; private LazySingleton(){}; public static LazySingleton getInstance(){ if (lazySingleton == null) { lazySingleton = new LazySingleton(); } return lazySingleton; } } public class HungrySingleton { private static final HungrySingleton hungrySingleton = new HungrySingleton(); private HungrySingleton(){}; public static HungrySingleton getInstance(){ return hungrySingleton; } } public class DoubleCheck { private volatile static DoubleCheck instance; private DoubleCheck(){}; public static DoubleCheck getInstance(){ if (instance == null) { //加锁 防止多线程 生成多个实例对象 synchronized (DoubleCheck.class){ if (instance == null) { return new DoubleCheck(); } } } return instance; } } public class InnerStaticSingleton { public InnerStaticSingleton(){ if (InnerClass.innerStaticSingleton != null) { throw new RuntimeException("不允许反射创建实例"); } } public static InnerStaticSingleton getInstance(){ return InnerClass.innerStaticSingleton; } private static class InnerClass{ private static final InnerStaticSingleton innerStaticSingleton = new InnerStaticSingleton(); } } public class EnumSingleton { private EnumSingleton(){}; public static EnumSingleton getInstance(){ return Enums.INSTANCE.getInstance(); } private enum Enums{ INSTANCE; private EnumSingleton enumSingleton; Enums(){ enumSingleton = new EnumSingleton(); } public EnumSingleton getInstance(){ return enumSingleton; } } }

    main:

    public class Main { public static void main(String[] args) { HungrySingleton h1 = HungrySingleton.getInstance(); HungrySingleton h2 = HungrySingleton.getInstance(); LazySingleton l1 = LazySingleton.getInstance(); LazySingleton l2 = LazySingleton.getInstance(); InnerStaticSingleton i1 = InnerStaticSingleton.getInstance(); InnerStaticSingleton i2 = InnerStaticSingleton.getInstance(); DoubleCheck d1 = DoubleCheck.getInstance(); DoubleCheck d2 = DoubleCheck.getInstance(); EnumSingleton e1 = EnumSingleton.getInstance(); EnumSingleton e2 = EnumSingleton.getInstance(); System.out.println("h1 :" + h1 + "===== h2 : " + h2 + "-----" + (h1.equals(h2))); System.out.println("l1 :" + l1 + "===== l2 : " + l2 + "-----" + (l1.equals(l2))); System.out.println("i1 :" + i1 + "===== i2 : " + i2 + "-----" + (i1.equals(i2))); System.out.println("d1 :" + d1 + "===== d2 : " + d2 + "-----" + (d1.equals(d2))); System.out.println("e1 :" + e1 + "===== e2 : " + e2 + "-----" + (e1.equals(e2))); } } h1 :com.demo.designpattern.singleton.HungrySingleton@3cd1a2f1===== h2 : com.demo.designpattern.singleton.HungrySingleton@3cd1a2f1-----true l1 :com.demo.designpattern.singleton.LazySingleton@2f0e140b===== l2 : com.demo.designpattern.singleton.LazySingleton@2f0e140b-----true i1 :com.demo.designpattern.singleton.InnerStaticSingleton@7440e464===== i2 : com.demo.designpattern.singleton.InnerStaticSingleton@7440e464-----true d1 :com.demo.designpattern.singleton.DoubleCheck@49476842===== d2 : com.demo.designpattern.singleton.DoubleCheck@49476842-----true e1 :com.demo.designpattern.singleton.EnumSingleton@78308db1===== e2 : com.demo.designpattern.singleton.EnumSingleton@78308db1-----true
    Processed: 0.042, SQL: 9