美文网首页
单例模式

单例模式

作者: Jorvi | 来源:发表于2018-11-16 09:56 被阅读0次

参考:
https://www.cnblogs.com/zhaoyan001/p/6365064.html


1. 恶汉式

public class Singleton {
    private static final Singleton instance = new Singleton();

    private Singleton() {
    }

    public static Singleton getInstance() {
        return instance;
    }
}

利用静态成员常量创建单例模式,简单、线程安全。

原理
类的静态常量,在类加载过程的准备阶段已经完成初始化,由JVM控制。


2. 懒汉式

public class Singleton {
    private static Class Inner {
        public static Singleton instance = new Singleton();
    }

    private Singleton() {
    }

    public static Singleton getInstance() {
        return Inner.instance;
    }
}

利用静态内部类创建单例模式,线程安全。

原理
一、根据Java语言规范,在首次发生下列任意一种情况时,一个类或接口类型T将被立即初始化(类加载的初始化阶段,此时加载、验证、准备已在此之前开始)。

  1. T是一个类,而且一个T类型的实例被创建;
  2. T是一个类,而且T中声明的一个静态方法被调用;
  3. T中声明的一个静态字段被赋值;
  4. T中声明的一个静态字段被使用,且这个字段不是一个常量字段;
  5. T是一个顶级类,而且一个断言语句嵌套在T内部被执行。

二、Java语言规范规定,对于每一个类或接口C,都有一个唯一的初始化锁LC与之对应。

  1. 当两个线程A和B试图同时初始化一个类(Class对象)时,会先去竞争Class对象的初始化锁,假设线程A获取到了初始化锁,那么线程B将一直等待获取初始化锁;
  2. 线程A发现Class对象还没有被初始化,开始执行类的静态初始化和初始化类中声明的静态字段;
  3. 线程A初始化完毕,唤醒所有等待初始化锁的线程,然后释放初始化锁;
  4. 线程B获取到初始化锁,根据锁的happens-before关系,可以确保线程A执行类的初始化时的写入操作,线程B一定可见,于是线程B会发现类已经初始化完毕,线程B释放初始化锁。

利用初始化锁控制线程安全性。


public class Singleton {
   
    private static volatile Singleton instance;

    private Singleton() {
    }

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

利用volatile+双重检查创建单例模式,线程安全。

原理
创建一个对象instance = new Singleton(),大致分为:

  1. 分配对象的内存空间;
  2. 初始化对象;
  3. 设置instance指向分配的内存地址。

如果不使用volatile变量,而是用普通变量的话:
在单线程中,2 和 3 是可以重排序的,并不影响结果。
在多线程中,2 和 3 重排序将可能导致未初始化完毕的对象在最外面一层判断null == instance时为false,而误认为对象已经初始化完毕了。

利用volatile将禁止2 和 3 的重排序,保证instance != null时,对象必定已经初始化完成。

相关文章

  • 【设计模式】单例模式

    单例模式 常用单例模式: 懒汉单例模式: 静态内部类单例模式: Android Application 中使用单例模式:

  • Android设计模式总结

    单例模式:饿汉单例模式://饿汉单例模式 懒汉单例模式: Double CheckLock(DCL)实现单例 Bu...

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

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

  • 设计模式之单例模式详解

    设计模式之单例模式详解 单例模式写法大全,也许有你不知道的写法 导航 引言 什么是单例? 单例模式作用 单例模式的...

  • Telegram开源项目之单例模式

    NotificationCenter的单例模式 NotificationCenter的单例模式分析 这种单例模式是...

  • 单例模式Java篇

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

  • IOS单例模式的底层原理

    单例介绍 本文源码下载地址 1.什么是单例 说到单例首先要提到单例模式,因为单例模式是单例存在的目的 单例模式是一...

  • 单例

    iOS单例模式iOS之单例模式初探iOS单例详解

  • 单例模式

    单例模式1 单例模式2

  • java的单例模式

    饿汉单例模式 懒汉单例模式

网友评论

      本文标题:单例模式

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