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

几种单例模式

程序员文章站 2022-07-13 23:39:38
...

几种单例模式

枚举可以天然防止反射和反序列化漏洞 需要延时加载时:枚举好于饿汉式 ,不需要延时加载:静态内部类好于懒汉式 也就是说优先选用 枚举和静态内部类

饿汉

/**
 * 饿汉式单例设计模式
 * 特点:线程安全、调用效率高、资源利用率低(无懒加载)。
 *
 * @author tiger
 * @Date 2017年9月2日
 */
public class SingletonHungry {
    // 私有构造函数
    private SingletonHungry() {  }

    // 单例对象,static是天然的线程安全
    private static SingletonHungry instance = new SingletonHungry();

    // 静态的工厂方法(访问本类的唯一入口)
    public static SingletonHungry getInstance() {
        return instance;
    }
}

懒汉1

对方法添加synchronized

/**
 * 懒汉式单例设计模式||特点:线程安全、调用效率低、资源利用率高(有懒加载)。
 * @author tiger
 * @Date 2017年9月2日
 */
public class SingletonLazy {
    // 私有化构造器
    private SingletonLazy() {}

    private static SingletonLazy instance = null;
    
    // 对方法进行同步(synchronized)并发效率低。
    public synchronized static SingletonLazy getInstance(){
        if (instance == null) {
            instance = new SingletonLazy();
        }
        return instance;
    }
}

懒汉2

静态内部类

/**
 * 静态内部类单例子模式
 * 特点:线程安全、兼备了高并发和延迟加载优势(有懒加载)。
 *
 * @author tiger
 * @Date 2017年9月2日
 */
public class SingletonLazyInnerClass {

    // 私有构造函数,杜绝反射机制破坏
    private SingletonLazyInnerClass() {
        if (LazyHolder.LAZY != null) {
            throw new RuntimeException("不允许创建多个实例");
        }
    }

    // 在静态内部类里创建类的实例
    private static class LazyHolder {
        private static final SingletonLazyInnerClass LAZY = new SingletonLazyInnerClass();
    }

    // 提供一个外界调用的公共方法,需要调用的时候才会初始化静态内部类,不需要线程同步,从而兼备了 
    // 高并发需求
    public static final SingletonLazyInnerClass getInstance() {
        // 在返回结果以前,一定会先加载内部类
        return LazyHolder.LAZY;
    }
}

懒汉3

双重检测锁+volatile

/**
 * 懒汉模式 -》 双重同步锁单例模式
 * 单例实例在第一次使用时进行创建
 */
public class SingletonDoubleCheck {

    // 私有构造函数
    private SingletonDoubleCheck() { }

    // 1、memory = allocate() 分配对象的内存空间
    // 2、ctorInstance() 初始化对象
    // 3、instance = memory 设置instance指向刚分配的内存

    // 单例对象 volatile + 双重检测机制 -> 禁止指令重排
    private volatile static SingletonDoubleCheck instance = null;

    // 静态的工厂方法
    public static SingletonDoubleCheck getInstance() {
        if (instance == null) { // 双重检测机制        // B
            synchronized (SingletonDoubleCheck.class) { // 同步锁
                if (instance == null) {
                    instance = new SingletonDoubleCheck(); // A - 3
                }
            }
        }
        return instance;
    }
}

懒汉4-推荐

枚举

/**
 * 枚举模式:最安全
 */
public class SingletonEnum {

    // 私有构造函数
    private SingletonEnum() { }

    public static SingletonEnum getInstance() {
        return LazyHolder.INSTANCE.getInstance();
    }

    // 枚举内部类
    private enum LazyHolder {
        INSTANCE;

        private SingletonEnum singleton;

        // JVM保证这个方法绝对只调用一次
        LazyHolder() {
            singleton = new SingletonEnum();
        }

        public SingletonEnum getInstance() {
            return singleton;
        }
    }
}

上一篇: php 单例模式

下一篇: php 单例模式