第二章面试题2:实现单例模式

本文介绍了单例模式的概念及其应用场景,并详细解析了懒汉式和饿汉式的实现方式及各自优劣。此外,还探讨了多线程环境下如何保证单例模式的线程安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是单例模式

Singleton:保证一个类只有一个实例,且提供一个访问它的全局访问点

为什么需要单例模式
  1. 有一些类只需要使用一个实例,如工具箱等
  2. 需要实现对唯一实例的受控访问
怎么实现单例模式

要求:

  1. 判断对象是否被实例化,若实例化了则直接使用实例
  2. 是否实例化应该由该类自己判断,不需要客户判断,不允许其他类实例该类,则需要构造方法私有化
  3. 客户通过该类的public方法使用实例
代码实现

单线程下

//懒汉式——需要时再创建(第一次使用时实例化)
public class Singleton{
   private static Singleton instance;

   private Singleton{};

   public static Singleton getInstance(){
       if(instance == null){
          instance = new Singleton(); 
       }
       return instance;
   } 
}
//饿汉式——一开始就创建好(初始化时创建实例)
public class Singleton{
   private static Singleton instance = new Singleton(); 

   private Singleton{};

   public static Singleton getInstance(){
        return instance;
   }
}

考虑多线程
懒汉式:考虑两个线程同时判断instance是否为空,两个判断全部为真,创建两个实例,线程不安全
饿汉式:一开始就创建好,后续部分不进行创建,线程安全

比较项目懒汉式饿汉式
含义第一次使用时创建类初始化时创建
优势与劣势当不需要时不创建,节约系统资源,线程不安全线程安全,浪费系统资源
多线程情况不安全安全
如何改进懒汉式和饿汉式
  1. 改进懒汉式

    //在第一次使用时创建,且针对实例是否为空加锁
    public class Singleton{
         private static Singleton instance;
    
         private Singleton{};
         //效果同直接在getInstance方法上加synchronized标签相同
         public static Singleton getInstance(){
             synchronized{
               if(instance == null){
                  instance = new Singleton();
               }
             }
             return instance;
         }
    }
    //缺点——当一个线程进入该方法后,其他线程都需要等待,性能上有损耗

    继续改进

    //双重校验锁——只有当实例为空的时候才进入同步代码块
    public class Singleton{
       private static Singleton instance;
    
       private Singleton{};
    
       public static Singleton getInstance(){
           if(instance == null){
               synchronized(this){
                  if(instance == null){
                      instance = new Singleton();
                  }
               }
           }
       }
    }
    //为什么要判断instance两次:
    //AB线程同时判断instance为空,A进入同步代码块,获得实例,此时instance为具体引用,B进入同步代码块,若不判断instance是否为空,则会重新创建一个新的实例。
  2. 改进饿汉式
//使用内部类
public class Singleton{

   private class InnerSingleton{
      private static Singleton instance = new Singleton();
   }

   public static Singleton getInstance(){

       return InnerSingleton.instance;
   }
}
//使用枚举类
public Enum Singleton{
   INSTANCE;
   public void otherMethod(){};

}

//使用方法
public static void Main(String[] args){
   Singleton.INSTANCE.otherMethod();
}

参考书目:
剑指offer第二版
大话设计模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值