1、单例模式

单例模式的核心在于维护某个类最多只包含一个实例,并且该实例只能由类自己来创建,对外提供接口获取唯一对象

饿汉式实现:在系统启动时创建唯一实例对象,缺点在于影响项目启动速度

public class HungrySingleton {

    private static final HungrySingleton singleton = new HungrySingleton();

    private HungrySingleton() {
    }

    public static HungrySingleton getSingleton() {
        return singleton;
    }

}

通过静态内部类实现饿汉式:

public class InsideSingleton {

    private static class inner {

        private static final InsideSingleton singleton = new InsideSingleton();

    }

    private InsideSingleton() {

    }

    public static final InsideSingleton getInstance() {
        return inner.singleton;
    }

}

通过枚举实现,天然保证单实例:

public enum EnumSingleton {

    singleton;

    public void method() {
    }

}

懒汉式实现:系统用到时访问,如果还没有就先创建,注意加锁防止初始化多次

public class LazySingleton {

    private static volatile LazySingleton singleton = null;

    private LazySingleton() {
    }

    public static synchronized LazySingleton getSingleton() {
        if (singleton == null) {
            singleton = new LazySingleton();
        }
        return singleton;
    }

}

懒汉式实现优化,不对整个方法加锁,采用双重校验锁:

public class LazySingleton2 {

    private static volatile LazySingleton2 singleton = null;

    private LazySingleton2() {

    }

    public static LazySingleton2 getSingleton() {
        if (singleton == null) {
            synchronized (LazySingleton2.class) {
                if (singleton == null) {
                    singleton = new LazySingleton2();
                }
            }
        }
        return singleton;
    }

}

注意双重校验锁实现必须通过 volatile 修饰,不禁止指令重排序可能报错,这个最后介绍

spring IOC 实际就用到单例模式,被 Spring 管理的类只包含唯一实例,用到时动态注入。简单总结:

  1. 构造方法必须私有,防止外部初始化
  2. 必须包含静态获取实例方法

其它方面根据具体场景选择:饿汉式影响启动,懒汉式延迟加载,需保证同步,各有利弊。


关于双重校验锁为何还要用 volatile 修饰:

对象初始化可以粗略分为以下三步:

  • 申请内存
  • 创建对象
  • 将引用指向对应内存

由于重排序的存在,上述步骤二三可能会颠倒,即先将引用指向对应内存,再将对象信息赋值到对应内存。此时假设不用 volatile 修饰,可能存在对象判断不为空,但实际还没有赋值的场景。此时返回引用,一旦调用方法就报错,因为对象实际还没有初始化完成,通过 volatile 禁止重排序就可以解决该问题

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值