单例模式(初学)

单例模式

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,因为另一个线程可能在获取锁之前就创建成功了,所以我们还需判断一次。

你可能感兴趣的:(单例模式,开发语言,java)