设计模式-单例模式

设计模式-单例模式

       单例模式是23种设计模式中较为简单的设计模式,面试中也是经常被面试官问到。但要真正在实际开发中运用好单例设计模式并不简单。本文主要介绍5种单例:饿汉式,懒汉式,懒汉式(内部静态类),注册式(枚举单例,threadlocal型单例(容器式))。前两种只要知道单例模式的人都知道,应付面试能讲出后三种绝对可以给自己加分。

       本文不提供测试结果!

  • 饿汉式 
/**
 * @description:饿汉式
 */
public class HungrySingleton {

    /**
     * final修饰,防止暴力反射破环单例
     *
     * 缺点:由于使用static修饰,不管单列是否被调用,对象在初始化时就会被创建,浪费空间
     */
    private static final HungrySingleton hungrySingleton = new HungrySingleton();

    private HungrySingleton() {

    }

    public static HungrySingleton getHungrySingleton() {
        return hungrySingleton;
    }

    /**
     * readResolve方法,防止序列化破坏单列
     * readResolve方法在反序列化创建对象时会用到
     */
    private Object readResolve(){
        return hungrySingleton;
    }

}

 

  • 懒汉式
**
 * @description:懒汉式,双重检验锁,保证多线程下的线程安全
 *
 * 双重检验锁,两次判断(lazySingleton == null),避免多线程时出现线程安全问题
 */
public class LazySingleton {

    private static LazySingleton lazySingleton = null;

    private LazySingleton() {}

    public static LazySingleton getInstance() {

        if (lazySingleton == null) {
            synchronized(LazySingleton.class) {
                if (lazySingleton == null) {
                    lazySingleton = new LazySingleton();
                }
            }
        }
        return lazySingleton;
    }
}
  • 懒汉式,内部静态类
/**
 * @description:懒汉式,内部静态类
 *
 * 内部类LazyHolder中的逻辑 :
 *【private  static final LazyInnerClassSingleton LAZY = new LazyInnerClassSingleton()】
 * 需要等到外部方法getInstance()被调用时才会执行,并不会因为static修饰在初始化时就加载。
 * 运用JVM底层运行逻辑,巧妙解决了线程安全问题
 * 代码中没有使用synchronized修饰,性能最优
 */
public class LazyInnerClassSingleton {

    private LazyInnerClassSingleton() {
        /**
         * 防止暴力反射,破坏单列
         */
        if (LazyHolder.LAZY != null){
            throw new RuntimeException("LazyHolder.LAZY 已被初始化");
        }
    }

    public static final LazyInnerClassSingleton getInstance() {
        return LazyHolder.LAZY;
    }

    private static class LazyHolder {
        private  static final LazyInnerClassSingleton LAZY = new LazyInnerClassSingleton();
    }
}
  • 注册式:枚举单例
**
 * @description:枚举单例,注册试(枚举)
 *
 * 不存在序列化和反射破坏单例的情况
 * JDK底层做了处理
 */
public enum  EnumSingleton {

    INSTANCE;

    private Object data;

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public static EnumSingleton getInstance() {
        return INSTANCE;
    }
}

 

  • 注册式:threadlocal型单例(容器式)
/**
 * @description:threadlocal型单例,注册试单例(容器试)
 * 伪线程安全,即在同一个线程中安全,多个线程调用getInstance()得到的实例不同
 * 可动态实现多数据源切换
 */
public class ThreadLocalSingleton {

    public ThreadLocalSingleton() {}

    public static final ThreadLocal<ThreadLocalSingleton> threadLocal =
            ThreadLocal.withInitial(() -> new ThreadLocalSingleton());

    public static ThreadLocalSingleton getInstance() {
        return threadLocal.get();
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值