单例模式

单例模式

核心作用

  • 保证一个类只有一个实例,并且提供一个访问该实例的全局访问点

常见场景

  • Windows的回收站、任务管理器
  • 项目中,读取配置文件的类,一般也只有一个对象,没有必要每次都去new对象读取
  • 数据库连接池的设计也是单例模式
  • 在Spring中,每个bean默认就是单例模式
优点:
  • 单例模式只有一个实例,减少了系统的开销
  • 可以在系统设置全局的访问点,优化共享资源访问

五种常见的实现单例模式的方式

  • 饿汉式(线程安全,调用效率高,不能延迟加载)
  • 懒汉式(线程安全,调用效率不高,可以延迟加载)
  • DCL懒汉式(由于JVM底层内部模型的原因,偶尔会出现问题,不建议使用)
  • 饿汉式改进 (静态内部类式:线程安全,调用效率高,可以延时加载)
  • 枚举单例(线程安全,调用效率高,不能延时加载,推荐使用
饿汉式
public class SingletonHunger {
    //1、私有化构造器
    private SingletonHunger(){}
    //2、类初始化的时候,立即加载该对象
    private static SingletonHunger instance=new SingletonHunger();
    //3、提供获取该对象的方法,没有synchronized,效率高
    public static SingletonHunger getInstance(){
        return instance;
    }
}
懒汉式
public class SingletonLazyer {
    //1、私有化构造器
    private SingletonLazyer(){}

    //2、类初始化的时候,不立即加载对象
     private static SingletonLazyer instance;

    //3、提供获取该对象的方法,有synchronized,效率低一些
    public static synchronized SingletonLazyer getInstance(){
        if (instance==null){
            instance=new SingletonLazyer();
        }
        return instance;
    }
}
DCL懒汉式(双重检测)

因为不是原子性操作,在极端情况下:

  • 1分配内存
  • 2执行构造方法
  • 3指向地址
  • 加volatile,保证线程对此变量修改时,另一个线程,该变量的缓存就失效,直接读取内存中的值,总之,一个线程如果改变了某个变量的值,在另外一个线程中是立即生效的
public SingletonDCLLazyer{
	//1、私有化构造器
	private SingletonDCLLazyer(){};
	//2、类初始的时候,不立即加载对象
	private volatile static SingtonDCLLazyer instance;
	//3、提供获取对象的方法,有synchrond,效率低一些
	private static SingletonDCLLazyer getInstance(){
	if(instance==null){
	 	 	synchronized(SingletonDCLLayer.class){
	 	 	if(instance=null){
	 	 	//检测为空,说明线城是第一个竞争到SingletonDCLLazyer这个锁的
	 	 		instance=new SingletonDCLLazyer();
	 	 		}
	 	 	}
	 	 }
	 	 return instance
	 }
}
饿汉改进式
public class SingletonHungerUpgrade {
    //1、私有化构造器
    private SingletonHungerUpgrade(){}

    //2、类初始化的时候,不立即加载对象
    private static class InnerClass{
        private  static  final SingletonHungerUpgrade instance  =  
        new SingletonHungerUpgrade();
    }
    static SingletonHungerUpgrade getInstance(){
        return InnerClass.instance;
    }//只有在调用getInstance的是时候才会加载内部类 -0
}
枚举单例
//枚举单例模式(不能延时加载,线程安全,最推荐,底层源码即屏蔽了反射对线程安全的破坏)
public enum SingletonEnum {
    //创建对象;
    INSTANCE;

    public SingletonEnum getInstance(){
        return INSTANCE;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值