聊聊“单例模式”的多种实现方式。

Posted HarLearn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了聊聊“单例模式”的多种实现方式。相关的知识,希望对你有一定的参考价值。

单例模式,可以保证你在系统的任何地方使用的实例都是同一个,也就是一个类只能创建一个实例,这样可以节省内存资源、保证数据内容的一致性。

单例模式(Singleton)定义,「保证一个类仅有一个实例,并提供一个访问它的全局访问点」。下面是类图:

单例模式

单例模式的思想就是保证类只有一个实例,所以剩下的问题就是利用编程语言的一些特性来实现这种思想。下面了解Java语言如何保证这种思想的。

在Java中所有类都有构造方法,不显示定义构造方法,系统会提供一个默认的构造方法,若有显示定义的构造方法,默认的构造方法就会失效。所以为了保证外界不可以通过new方法创建多个实例,我们把构造方法私有化。并向外界提供一个静态的方法,来让外界创建和使用类。

单例模式有多种实现方式,下面进行简要的了解。

普通单例模式

聊聊“单例模式”的多种实现方式。

现在的操作系统都使用抢占式调度,也就是每一个可运行线程都只有一个时间片来执行任务。当时间到达时就会让其他线程来执行任务。所以在上述代码中,单例首次被调用时,singleton肯定是null的。当线程A首次使用单例时,会通过null判断,再进行实例化,但是时间片结束,没有实例化成功。换其他线程来执行任务,当轮到线程B时,它也要使用单例,线程B在判断时条件也为null,也会进行实例化操作。所以会有多个线程通过判断进入来创建实例,违背单例模式的思想。解决方式就是加锁,让其创建过程变成同步的,必须实例化完成才可以。看下面多个实现方式。

懒汉式单例

聊聊“单例模式”的多种实现方式。

synchronized关键字锁住的是这个对象,这样的用法,在性能上会有所下降,因为每次调用getInstance(),都要对对象上锁,事实上,只有在第一次创建对象的时候需要加锁,之后就不需要了,所以,这个地方需要改进。

双重锁定模式

聊聊“单例模式”的多种实现方式。

双重锁定模式是对上一种的改进,让其只在首次使用时才加锁。

饿汉式单例

我们也可以利用类加载顺序,让类加载时就创建一个单例,保证在调用 getInstance 方法之前单例已经存在了。并设置为常量,保证以后不再修改,所以是线程安全的,看下面代码:

聊聊“单例模式”的多种实现方式。

这种方式就是在类加载时就创建一个单例,不管你使不使用,都会进行创建。如果始终都没有使用Singleton实例,那么创建Singleton消耗的系统资源就被白白浪费了。

初始化块方式实现

还有一种初始化方式,是使用初始化块进行初始化,利用初始化块在类加载时只会执行一次的特性。看下面代码实现。

聊聊“单例模式”的多种实现方式。

内部类方式实现

在学习过程中也看到有使用内部类来实现单例模式的。因为类的加载过程是线程互斥的。这样当我们第一次调用getInstance的时候,JVM能够帮我们保证instance只被创建一次。代码如下:

总结

单例模式的本质还保证一个类只有一个实例的要求。上面学习了在Java语言中实现这种思想的几种实现方法,还有很多实现方法,都有其优缺点。结合各个方法的优点,根据自己的需求选择合适的就可以。取长补短。

公众号:HarLearn


以上是关于聊聊“单例模式”的多种实现方式。的主要内容,如果未能解决你的问题,请参考以下文章

Java单例模式 多种实现方式

聊聊如何使用单例模式

java学习-单例模式的多种实现方式

单例模式

单例模式详解

面试官说要10个单例模式的实现方式,呐,给你10个