美文网首页
设计模式 - 单例

设计模式 - 单例

作者: nzdxwl | 来源:发表于2019-11-15 23:23 被阅读0次

当我们希望某个类在应用程序执行过程中有且仅有一个实例的时候,就可以用到单例模式了。

双重检查加锁方式:

// final类不被继承
public final class DCLSingleton {
    private static volatile DCLSingleton instance;    

    //单例中我们要获取的资源
    public Resource resource = null;

    private DCLSingleton() {
        //...这里进行resource的创建
        resource = ... ;
    }
    
    /**
     * 双重校验,当instance不为null时,获得当前类的锁,然后再次判断instance是否等于null:
     * 这是为防止在多个线程调用情况下,当线程A判断instance为null,获得类锁后,创建新的实例,
     * 此时如果新的实例还未创建完毕时,线程B判断instanc为null,在进行类锁获取时,线程A刚好创建完实例释放类锁,并由线程B获得,
     * 那么如果没有第二个等于null的判断的话,则又会创建另一个新的实例。所以这种单例模式就称为双重检查加锁模式。
     * @return
     */
    public static DCLSingleton getInstance() {
        if(instance == null) {
            synchronized(DCLSingleton.class) {
                if(instance == null) {
                    instance = new DCLSingleton();
                }
            }
        }
        
        return instance;
    }
}

上面的方式看起来做了很充分的检查,但在多线程情况仍有可能出现空指针异常:
我们在私有构造器中进行资源实例化,还有单例自身,根据JVM运行时指令重排序和Happens-Before规则,这两者的实例化顺序并无前后关系的约束,有可能单例实例最先被实例化,而资源尚未完成实例化,此时其他线程此时调用getInstance()方法获得单例实例,如果直接调用resource方法则会抛出空指针异常。

以下是改进后的单例实现:
Holder方式:

public final class HolderSingleton {

    // 私有构造器
    private HolderSingleton() {
        // ...资源实例创建
    }

    // 私有静态类
    private static class Holder {
        private static HolderSingleton instance = new HolderSingleton();
    }

    //通过内部静态类来创建实例
    public static HolderSingleton getInstance() {
        return Holder.instance;
    }
    //单例中的资源    
    private static Resource resource = null;

    public static Resource getResource() {
        return resource;
    }

}

instance被放置到静态内部类Holder中,HolderSingleton类的初始化不会创建实例,当Holder被主动引用时才创建。

相关文章

  • 单例模式Java篇

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

  • python中OOP的单例

    目录 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式设计模式 是 前人...

  • 单例

    目标 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式设计模式 是 前人...

  • python 单例

    仅用学习参考 目标 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式设计...

  • 2018-04-08php实战设计模式

    一、单例模式 单例模式是最经典的设计模式之一,到底什么是单例?单例模式适用场景是什么?单例模式如何设计?php中单...

  • 设计模式第二篇、单例设计模式

    目录1、什么是单例设计模式2、单例设计模式的简单实现3、单例设计模式面临的两个问题及其完整实现4、单例设计模式的应...

  • 设计模式 - 单例模式

    设计模式 - 单例模式 什么是单例模式 单例模式属于创建型模式,是设计模式中比较简单的模式。在单例模式中,单一的类...

  • 2、创建型设计模式-单例设计模式

    江湖传言里的设计模式-单例设计模式 简介:什么是单例设计模式和应用 备注:面试重点考查 单例设计模式:这个是最简单...

  • 设计模式之单例模式

    单例设计模式全解析 在学习设计模式时,单例设计模式应该是学习的第一个设计模式,单例设计模式也是“公认”最简单的设计...

  • 设计模式

    常用的设计模式有,单例设计模式、观察者设计模式、工厂设计模式、装饰设计模式、代理设计模式,模板设计模式等等。 单例...

网友评论

      本文标题:设计模式 - 单例

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