设计模式(一)单例模式

单例模式

一、定义

  • 确保一个类在任何情况下都只有一个实例,且提供一个全局访问点
  • 隐藏所有的构造方法(拒绝外部类初始化保证只有一个实例)
  • 属于创建者模式
  • 使用场景:ServletContext、ServletConfig、ApplicationContext、DBPool

二、写法

  • 饿汉式
  • 懒汉式
  • 注册式
  • ThreadLocal单例

饿汉式

  • 优点:效率高、性能高、不需要锁(jvm加载机制只会加载一次)
  • 缺点:可能会造成内存浪费
    在这里插入图片描述

懒汉式

  • 优点:节省内存
  • 缺点:线程不安全(很可能调用的时候返回不同的实例,所以要加锁)

//同步锁
//第一次使用getInstance()需要同步,后面getInstance()不需要同步;每次同步,效率很低
public class SingleTon(){
   private SingleTon(){
   }
   private static SingleTon singleton = null;
   public synchronized static getInstance(){
     if(singleton == null){
	   singleton = new SingleTon();
	 }
	  return singleton ;
   }
}
原文链接:https://blog.csdn.net/jike11231/article/details/106229415/
//双重锁
//安全且在多线程情况下能保持高性能。
//实例变量需要加volatile 关键字保证易变可见性
public class SingleTon4{
  private SingleTon4(){
  }
  private volatile static SingleTon4 singleton4 = null;
  public static SingleTon4 getSingleton(){
  //是否要阻塞
     if(singleton4 == null){
        synchronized (SingleTon4.class){
        //是否要创建
          if(singleton4 == null){
 		      singleton4 = new SingleTon4();
 		      //指令重排序问题,所以用volatile 
 		  }
		}
	 }
	  return singleton4 ;
  }
}

原文链接:https://blog.csdn.net/jike11231/article/details/106229415/
//静态内部类模式
//利用了JVM类加载机制来保证初始化实例对象时只有一个线程,
//静态内部类SingletonHolder类只有第一次调用getInstance方法时,才会装载从而实例化对象
//会被反射破坏
public class Singleton5{
  private SingleTon5 (){
  }
  private static class SingletonHolder{
       private static final Singleton5 = new Singleton5();
  }
  public static final Singleton5 getInstance() {
       return SingletonHolder.Singleton5 ;
  }
} 
//反射破坏
public class Test {
     public static void main(String args[]) {
		    private Singleton() {};
            Singleton singleton = Singleton.getInstance();
        	try {
            Constructor<Singleton> constructor = Singleton.class.getDeclaredConstructor();
            constructor.setAccessible(true);//强制
            Singleton singletonnew = constructor.newInstance();
            System.out.println(singleton == singletonnew);
            //输出结果为 false
        } catch (Exception e) {
 
        }     
    }
}
//解决方案:可以给构造函数加上判断,限制创建多个实例
private Singleton() {
     if (null != Singleton.singleton) {
         throw new RuntimeException();
    }
}

原文链接:https://blog.csdn.net/jike11231/article/details/106229415/

注册式单例

  • 将每一个实例缓存到同意容器中,使用唯一标志获取实例

  • 线程不安全

在这里插入图片描述

在源码里的应用

1.AbstractFactoryBean:里的getObject方法
2.ErrorContext:错误日志
在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值