java设计模式-单例模式

单例模式

  1. 懒汉模式
public class Singleton_01 {
    //懒汉模式(线程不安全)
     public  static Singleton_01 instance;
     private Singleton_01() {
     }
     
       public   static  Singleton_01  getInstance(){
          if(instance!=null){
                return  instance;
          }
          instance=new Singleton_01();
            return instance;
       }
       //

}
  • 单例模式有⼀个特点就是不允许外部直接创建,也就是new Singleton_01(),因此这⾥在默认的构造函数上添加了私有属性 private。
  • ⽬前此种⽅式的单例确实满⾜了懒加载,但是如果有多个访问者同时去获取对象实例你可以想象成⼀堆⼈在抢厕所,就会造成多个同样的实例并存,从⽽没有达到单例的要求。
  1. 线程安全的懒汉模式
    直接用锁实现
public class Singleton_01 {
    //懒汉模式(线程不安全)
     public  static Singleton_01 instance;
     private Singleton_01() {
     }
     
       public   static  synchronized   Singleton_01  getInstance(){
          if(instance!=null){
                return  instance;
          }
          instance=new Singleton_01();
            return instance;
       }
       //

}
  • 此种模式虽然是安全的,但由于把锁加到⽅法上后,所有的访问都因需要锁占⽤导致资源的浪费。如果不是特殊情况下,不建议此种⽅式实现单例模式。
  1. 饿汉模式
    线程安全
public class Singleton_02 {
    //恶汉模式(线程安全)
     public  static  Singleton_02 instance=new Singleton_02();
      private Singleton_02() {
          
      }
       public   static  Singleton_02 getInstance(){
            return instance;
       }
}
  • 但此种⽅式并不是懒加载,也就是说⽆论你程序中是否⽤到这样的类都会在程序启动之初进⾏创建。
  • 那么这种⽅式导致的问题就像你下载个游戏软件,可能你游戏地图还没有打开呢,但是程序已经将这些地图全部实例化。到你⼿机上最明显体验就⼀开游戏内存满了,⼿机卡了,需要换了。
  1. 使用类的内部类(线程安全)
    静态类部类
public class Singleton_03 {
    // 静态内部类
   public  static  class  SingletonHolder{
         private  static  Singleton_03   instance=new Singleton_03();
   }
     private  Singleton_03(){
       
     }
   public   static  Singleton_03  getInstance(){
         return SingletonHolder.instance;
   }
}
  • 使⽤类的静态内部类实现的单例模式,既保证了线程安全有保证了懒加载,同时不会因为加锁的⽅式耗费性能。
  • 这主要是因为JVM虚拟机可以保证多线程并发访问的正确性,也就是⼀个类的构造⽅法在多线程环境下可以被正确的加载。
  • 此种⽅式也是⾮常推荐使⽤的⼀种单例模式
  1. 双重锁校验(线程安全)
public class Singleton_04 {
    private  static   Singleton_04 instance;
    private Singleton_04() {
    }
    public  static Singleton_04  getInstance(){
          if(instance!=null){
                return  instance;
          }
          synchronized (Singleton_04.class){
                if(instance==null){
                     instance = new Singleton_04();
                }
          }
      return instance;
    }
}
  • 双锁的⽅式是⽅法级锁的优化,减少了部分获取实例的耗时。同时这种⽅式也满⾜了懒加载。
  • 同时这种⽅式也满⾜了懒加载。
  1. 枚举方式(推荐)
public class SingletonObject7 {
    private SingletonObject7(){
    }
    /**
     * 枚举类型是线程安全的,并且只会装载一次
     */
    private enum Singleton{
        INSTANCE;
        private final SingletonObject7 instance;
        Singleton(){
            instance = new SingletonObject7();
        }
        private SingletonObject7 getInstance(){
            return instance;
        }
    }
    public static SingletonObject7 getInstance(){
        return Singleton.INSTANCE.getInstance();
    }
}
  • 这种⽅式解决了最主要的;线程安全、⾃由串⾏化、单⼀实例。

参考资料:

  • 重学java设计模式
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值