两种比较“强壮”的单例代码。

本文介绍了两种实现单例模式的方法:双重检查锁定和静态内部类。详细解析了它们的工作原理及优缺点,帮助读者理解如何在Java中正确地实现单例模式。

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

第一种:

public class SingletonClass{
    private static SingletonClass instance = null;
    public static SingletonClass getInstance(){
        if(instance == null){
            synchronized(SingletonClass.class){
                if(instance == null){
                instance = new SingletonClass();
                }
            }
        }    
        return instance;
    }
    private SingletonClass(){
    
    } 
}


此种方法采用了将构造方法改为“private”来修饰,这样就使得用户无法通过用new的方式来获得这个类的实例,但此类提供了一个供外部获得唯一实例的static方法getInstance(),当getInstance()方法第一次被调用时instance这个属性一定是为空的,当instance为空的时候要new一个实例出来,new出的这个实例也是程序运行过程中唯一的实例。

<span style="white-space:pre">	</span>if(instance == null){
            synchronized(SingletonClass.class){
                if(instance == null){
                instance = new SingletonClass();
                }
            }
        }    
        return instance;

这是getInstance()方法中的全部代码,我们先看synchronized(){}这段,为什么这是一个“强壮”的单例呢,就是因为下面这条语句synchronized(){},如果不加synchronized(){}的话如果有多线程同时来调用getInstance()方法,就会可能就会导致单例模式的失效,出现多个实例。例如:A和B先后调用getInstance(),A线程第一次调用getInstance()方法时判断if为空,程序将会向下执行new实例的代码,不用多想一定会new一个实例,但当A想往下执行new一个新实例时CPU将控制交给了B线程,B在执行if语句时也判断为空,也不用多想,它执行了下面语句new出一个实例,些时CPU又回到A线程执行下面创建实例的代码,这时就出现了单例类矛盾的出现了两个实例。

所以,使用synchronized(){}代码是将判断instance是否为空和为空之后new实例的的代码在被多个线程调用的过程中只能有一个线程执行。大家会看到为什么要有两个if(instance == null)的判断呢,这是因为如果没有最外面的if判断时每次调用getInstance()方法时都会执行synchronized(){}代码,但每次执行synchronized(){}代码会比较慢,

所以考虑到性能的原因最外面先判断instance是否为空在决定是否执行synchronized(){}代码。

第二种:

public class SingletonClass { 
  
    private static class SingletonClassInstance { 
        private static final SingletonClass instance = new SingletonClass(); 
    } 

    public static SingletonClass getInstance() { 
        return SingletonClassInstance.instance; 
    } 

    private SingletonClass() { } 
}

第二程实现的单例的方法使用了static的内部类,getInstance()方法返回的是内部类中instance属性,内部类内的instance属性用static final修饰,不管调用getInstance()方法被调用多少次,或被多个线程同时调用,都只会有一个实例存在。第二种方法比较推荐,只是使用了简单的内部类。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值