单例模式(初学)-CSDN博客

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

单例模式

1、概念

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

2、方式

  • 怎么样来保证只有一个类的实例呢

    • 我们可以将类的构造器私有让用户不能在new对象让类自身负责保存它的唯一实例,并提供一个全局访问点。

3、代码

  • public class Singleton01 {
    
    	private static Singleton01 instance;  //这个属性要变为static全局
    	
    	private Singleton01() {   //构造方法为私有是防止用户new对象
    		
    	}
    
    	public static Singleton01 getInstance() { //全局访问点
    			if(instance == null) {              
    				instance = new Singleton01();
    			}
    		return instance;
    	}
    }
    

4、改进双重检查锁定

  • 上述就是单例模式的一个简单的代码了但是我们会发现一个问题

    • 当多个线程访问时可能会出现重复new对象的情况导致实例不唯一
      • 遇到这种情况我们可以对代码进行加锁来约束
  • public class Singleton01 {
    
    	private volatile static Singleton01 instance;  //这个属性要变为static全局volatile关键字是为了避免发生指令重排序
    	private Singleton01() {   //构造方法为私有是防止用户new对象
    		
    	}
    
    	public static Singleton01 getInstance() { //全局访问点
    		
    		if (instance == null) {   // 1
    			synchronized(Singleton01.class) {   //2、加锁防止多线程访问时多new一个对象
    				//当判断没有对象的时候new对象有对象生成的时候不重新生成对象达到单例的要求
    				if(instance == null) {       //3      
    					instance = new Singleton01();  //4
    				}
    			}
    		}
    		return instance;
    	}
    }
    
    • 上述代码我们可以看到我们对创建唯一实例的代码进行了加锁处理但是同时我们也可以看到有两个判断为null 的判断语句为什么呢

      • 当代码运行到 1 处时判断有实例后就会直接返回实例大大减少了synchronized的开销。
      • 当实例为 null 时使用synchronized关键字在多线程环境中避免多次创建对象。
      • 当代码运行到 3 处再次判断是否为null因为另一个线程可能在获取锁之前就创建成功了所以我们还需判断一次。
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6