java单例模式中懒汉式的线程安全问题

单例模式是在开发中经常使用的设计模式,饿汉式自然是不存在线程安全问题的,但是为了节约系统开销,经常会 用到懒汉式。

public class Singleton {
    //单例模式
    //懒汉式
    private static Singleton singleton=null;
    private Singleton(){
    }
    public static Singleton getSingle(){
        if (singleton==null)
            return new Singleton();
        return singleton;
    }
}

这是最基本的懒汉式写法

懒汉式在单线程情况下不会存在问题,但是在多线程的情况下,线程安全问题不可忽略。

通过双重检测机制加锁是否能实现线程安全??

public class Singleton {
    //单例模式
    //懒汉式双重检测机制加锁
    private static Singleton singleton=null;
    private Singleton(){
    }
    public synchronized static Singleton getSingle(){
      
        if (singleton==null){
            synchronized (Singleton.class){
                if (singleton==null)
                    return singleton;
            }
        }
        return singleton;
    }
}

这就要从JVM和CPU优化着手进行分析了

java在创建对象的过程中主要有三个步骤

1、分配对象的内存空间

2、设置instance指向刚分配的内存

3、初始化对象

但是在创建的过程中,由于JVM和CPU优化,2和3这两个步骤是可以发生指令重排的,这就导致了多线程情况下,会返回没经过初始化的对象

如何解决?

通过volatile关键字实现多线程的可见性,标记对象创建的状态

public class Singleton {
    //单例模式
    private static volatile Singleton singleton=null;
    private Singleton(){
    }
    public  static Singleton getSingle(){
        //双重检测机制加锁,实现线程安全
        if (singleton==null){
            synchronized (Singleton.class){
                if (singleton==null)
                    return singleton;
            }
        }
        return singleton;
    }
}
发布了117 篇原创文章 · 获赞 17 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/Jack__iT/article/details/92801991