23种设计模式笔记--单例模式

Posted Simon格子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了23种设计模式笔记--单例模式相关的知识,希望对你有一定的参考价值。

单例模式:
public class SingletonDoubleLock

    private SingletonDoubleLock() // 关键点0:构造函数是私有的

    private volatile static SingletonDoubleLock singleton = null; // 关键点1:声明单例对象是静态的

    public static SingletonDoubleLock getInstance() // 通过静态方法来构造对象
   
        if (null == singleton) // 关键点2:判断单例对象是否已经被构造
       
            synchronized (SingletonLock.class) // 关键点3:加线程锁
           
                if (null == singleton) // 关键点4:双重判断单例对象是否被构造
               
                    singleton = new SingletonDoubleLock(); 
               
           
       
        return singleton;
   

单例是为了保证系统中只有一个实例,其关键点有5

一.私有构造函数

二.声明静态单例对象

三.构造单例对象之前要加锁(lock一个静态的object对象)

四.需要两次检测单例实例是否已经被构造,分别在锁之前和锁之后

五.使用volatile修饰singleton


可能会提问系列:

0.为何要检测两次?

如上面所述,有可能延迟加载或者缓存原因,造成构造多个实例,违反了单例的初衷。

1.构造函数能否公有化?

不行,单例类的构造函数必须私有化,单例类不能被实例化,单例实例只能静态调用

2.lock住的对象为什么要是object对象,可以是int吗?

不行,锁住的必须是个引用类型。如果锁值类型,每个不同的线程在声明的时候值类型变量的地址都不一样,那么上个线程锁住的东西下个线程进来会认为根本没锁,相当于每次都锁了不同的门,没有任何卵用。而引用类型的变量地址是相同的,每个线程进来判断锁多想是否被锁的时候都是判断同一个地址,相当于是锁在通一扇门,起到了锁的作用。

3.为什么使用volatile修饰singleton?
singleton = new SingletonDoubleLock()时分以下三步进行:分配内存空间、初始化对象、将singleton指向分配的内存地址。
由于 JVM 具有指令重排的特性,有可能执行顺序变为了 1>3>2或者2>1>3

以上是关于23种设计模式笔记--单例模式的主要内容,如果未能解决你的问题,请参考以下文章

23种设计模式

GOF23—单例模式

23种设计模式笔记--单例模式

GOF23设计模式之单例模式(singleton)

Java 设计模式-单例模式

设计模式-单例模式