美文网首页
java懒汉式单例为什么是两次非空校验?

java懒汉式单例为什么是两次非空校验?

作者: 放羊娃华振 | 来源:发表于2022-09-05 22:54 被阅读0次

最近被问到单例为什么一定要进行两次非空的判断?我当时大脑就不转了!晚上我围着小区散散步忽然想起了这个问题,我静静的思考了下,其实我是能答的,但是当时头昏脑涨的就一下乱套了,所以遇到事情还是不要慌,先梳理下基础知识冷静的分析下。

首先我们看看单例双重检验的代码实现:

public class SingleInstance {
    private static volatile SingleInstance instance;
    private SingleInstance() {
    }
    public static SingleInstance getInstance() {
        if (instance == null) { //第一层
            synchronized (SingleInstance.class) {
                if (instance == null) {  //第二层
                    instance = new SingleInstance();
                }
            }
        }
        return instance;
    }
}

getInstance()方法第一层非空判断其实就是使用缓存的思想,过滤掉重复竞争锁的逻辑。我们不妨去掉这行代码:

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

这是不是就一目了然了,要是没有第一次非空判断,每次都会走竞争锁的逻辑,也是不必要的资源开销。

再讨论下getInstance()方法的第二层非空判断,它的作用就是阻止多线程的情况下重复创建实例对象。我们不妨去掉这行代码:

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

此时可以看出要是多线程的情况下,多个线程都走到了竞争锁的位置,当第一个线程执行完后释放锁,另外的线程拿到锁还能继续创建对象,此处加了一层非空判断就是规避了此问题。

相关文章

  • kotlin实现单例模式

    1.懒汉式实现单例模式 2.线程安全懒汉式实现单例模式 3.双重校验懒汉式实现单例模式 4.静态内部类方式实现单例模式

  • Kotlin 的单例模式

    Kotlin 的单例模式(5种) Kotlin 的5种单例模式: 饿汉式 懒汉式 线程安全的懒汉式 双重校验锁式 ...

  • java懒汉式单例为什么是两次非空校验?

    最近被问到单例为什么一定要进行两次非空的判断?我当时大脑就不转了!晚上我围着小区散散步忽然想起了这个问题,我静静的...

  • 我要做 Android 之单例模式

    Q:实现单例模式有几种方法?懒汉式中双层锁的目的是什么?两次判空的目的又是什么? 懒汉式(线程不安全) 单例模式最...

  • 单例模式-懒汉式-Java双重校验锁🔒

    单例模式 饿汉式: 懒汉式: 双重校验锁? 问题解惑: 1、为什么synchronized关键字要放在Single...

  • 深入理解单例模式

    前言 ​ 单例模式有很多种形式:饿汉式、懒汉式、DCL(双重校验)、静态内部类、容器单例、ThreadLoca...

  • 单例模式Java篇

    单例设计模式- 饿汉式 单例设计模式 - 懒汉式 单例设计模式 - 懒汉式 - 多线程并发 单例设计模式 - 懒汉...

  • 关于java单例模式,这篇已经讲得很清楚了,建议收藏!

    概念 java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。 特点 单例...

  • 每天一个设计模式

    1.单例模式 懒汉式,线程不安全 懒汉式,线程安全 饿汉式 双检锁/双重校验锁(DCL,即 double-chec...

  • JAVA多线程之线程安全的单例模式

    概念:java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。单例模式有一...

网友评论

      本文标题:java懒汉式单例为什么是两次非空校验?

      本文链接:https://www.haomeiwen.com/subject/mmewnrtx.html