单例模式纠错

忽然发现之前写的单例有问题,如下:

public class Singleton{

private static Singleton instance = null ;

private Singleton() {}

public static Singleton getInstance() {  

    if (instance == null) {  

         synchronized (instance) {

            if(instance == null){

                 instance =new Singleton();

            } } }  

    return instance;  

}  }

首先说说同步,synchronized 加在了内部,对性能会有一定提升。当调用的时候是不需要加锁的,只有在instance为null,并创建对象的时候才需要加锁。

开篇说的有问题是在多线程中这样写可能拿到未初始化的instance。why?

我们以A和B两个线程为例,当A和B同时进入第一个if判断时:

A首先进入synchronized块,由于instance为null,所以它执行instance = new Singleton();

因为instance = new Singleton()分两步执行,但不保证执行的先后顺序。有可能JVM会为新的Singleton实例分配空间,然后直接赋值给instance成员,然后再去初始化这个Singleton实例。

如果A在没有开始初始化这个实例时离开同步块,此时instance不空,但未初始化。

B在这个时候进入synchronized块,instance不空,会直接返回未初始化的instance。

怎么解决:

方案1:分离开创建的过程,给创建过程加同步锁。

public class Singleton{

private static Singleton instance = null ;

private Singleton() {}

public static Singleton getInstance() {  

    if (instance == null) {  initInstance(); }  

    return instance;  

private static synchronized void initInstance() {

    if(instance == null){

        instance =new Singleton();

    }} 

}

方案2:使用内部类来维护单例的实现

public class Singleton{

private Singleton() {}

public static     getInstance() { return SingletonFactory.instance;  } 

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

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 前言 本文主要参考 那些年,我们一起写过的“单例模式”。 何为单例模式? 顾名思义,单例模式就是保证一个类仅有一个...
    tandeneck阅读 7,239评论 1 8
  • 单例模式(Singleton Pattern)是众多设计模式中较为简单的一个,同时它也是面试时经常被提及的问题,如...
    廖少少阅读 3,701评论 0 1
  • 单例模式 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属...
    Graddy阅读 3,068评论 0 0
  • 单例:意思就是只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单...
    CoderZS阅读 3,690评论 1 13
  • 单例模式(Singleton Pattern)是 编程语言中最简单的设计模式之一。这种类型的设计模式属于创建型模式...
    Hi夜城阅读 3,229评论 1 10