设计模式:单例模式(Singleton)

设计模式是对已有问题固定的解决方法的总结。
单例模式: (单例:单个实例)  
单例模式保证只有一个实例,就要保证外界不能随便的new这个对象,所以要 私有化构造方法
私有化构造方法后就是把 new这个对象控制权收回了,只能在类内部去实例化这个对象, 让类自身负责保存他的唯一实例。 
单例模式(Singleton)保证一个类仅有一个实例,并提供一个访问他的全局访问点。
保证类仅有一个实例最好的办法就是,让类自身负责保存他的唯一实例。这个类可以保证没有其他实例被创建,并且他可以提供一个访问该实例的方法。
从时间空间上看:以空间换时间 
从线程安全上看:安全的
所以又叫“饿汉式”(还没有使用就实例化了)
public class Singleton {
   //3、定义一个变量来存储创建好的类实例
   //直接在这里创建类实例,由虚拟机来保证只会创建一次
   //这个类加载到内存的时候就会创建唯一的一份实例
   private static final Singleton instance = new Singleton();
   
   //1.私有化构造方法,好在内部控制创建实例的数目
   private Singleton() {
      
   }
   
   //2、定义一个方法来为客户端提供类实例
    //这个方法需要定义成类方法,也就是要加static
   public static Singleton getInstance() {
      //4、直接使用已经创建好的实例
      return instance;
   }
}
从时间空间上看:以时间换空间
从线程安全上看:不安全的(所以要加锁synchronized)
所以又叫“懒汉式”(也就是在用到的时候才去实例化)
 
public class Singleton1 {
   //3、定义一个变量来存储创建好的类实例
   //因为这个变量要在静态方法中使用,所以需要加上static修饰
   private static Singleton1 instance = null;
   
   //1.私有化构造方法,好在内部控制创建实例的数目
   private Singleton1() {
      
   }
   
   //2、定义一个方法来为客户端提供类实例
   //这个方法需要定义成类方法,也就是要加static
   public synchronized static Singleton1 getInstance() {
      //4、判断这个实例是不是有值
      if (instance == null) {
         //5、如果没有,就创建一个类实例,并把值
         //赋给存储类实例的变量
         instance = new Singleton1();
      }
      return instance;
   }
}
加锁有线程安全的问题:
Singleton singleton1 = Singleton. getInstance();
Singleton singleton2 = Singleton. getInstance();
System. out.println(singleton1 == singleton2); //true 是同一个对象

被volatile修饰的变量的值,将不会被本地线程缓存所以对该变量的读写都是直接操作共享内存,从而保证多个线程能正确的处理改变量。volatile一个线程修改了值,其他线程可以读取的到。
如果实例存在就没有必要走同步的必要,如果实例不存在才会进入同步块。
这样只会在第一次创建的时候同步一次,其余的时候不需要同步。
第二重检查是因为:当A线程执行 new Singleton()时候,B线程正在执行第一重检查if(instance == null)此时B线程会进入,
所以在synchronized中要再做一次检查。因为instance是volatile修饰的所以A线程new Singleton修改了instance的时候,
在B线程中能读取到instance不是null。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值