欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java设计模式-单例模式

程序员文章站 2022-03-18 15:30:01
转载请注明原文地址: http://www.cnblogs.com/geekda/p/9033815.html 单例模式是23种设计模式中比较常见的一种创建式模式,使用单例模式的目的就是为了节省系统资源,做到一次定义,到处使用的效果,目前使用比较广泛的场景是spring 的bean,使用的是注册式单 ......

转载请注明原文地址: http://www.cnblogs.com/geekda/p/9033815.html

  单例模式是23种设计模式中比较常见的一种创建式模式,使用单例模式的目的就是为了节省系统资源,做到一次定义,到处使用的效果,目前使用比较广泛的场景是spring 的bean,使用的是注册式单例模式,而在常见的开发中,实现单例模式还有如下几种方式:

1,饿汉式

饿汉式单例模式比较典型的特点,就是对象初始化的时候就已经创建好了,相比于懒汉模式不足之处是相对更耗资源,好处是不存在线程安全问题,代码如下:

java设计模式-单例模式

2,懒汉式

懒汉式单例模式的设计原则是单例对象初始化的时候是为空的,谁第一个用就会先创建对象,后续的方法则返回第一次创建的对象,这种方式目前存在线程安全问题

代码如下:

java设计模式-单例模式

3,懒汉式-加锁版本

上面懒汉模式由于存在线程安全问题,故需要加锁来解决此问题,代码如下:

java设计模式-单例模式

此种方式加锁虽然能解决线程安全问题,但是此处加锁在线程量大的情况会带来性能问题,下面提供一种比较好的解决方法双重校验锁方式

4,双重校验锁

此方式不仅能保证线程安全,还能提供解决性能问题,一举两得。代码如下:

java设计模式-单例模式

假如有两个线程,同时访问此方法第一个判断是校验在单例对象是否已创建,创建好则直接返回,没有创建则进入到同步块中,同步块中加一个判断的

作用是判断此处刚好没创建实例,则继续创建实例,此处需要说明的是其中一个线程如果已经进入同步块中创建好对象,由于多线程环境中对象创建的字节码是无序的,

所以另外一个线程可能拿到的是一个未完全初始化的对象了,为了解决此问题,我们在定义成员变量上加一个关键字:volatile,可以保证对象有序性,即保证了可见性,

这样另外一个线程拿到的就是一个完整的对象。

5,静态内部类

这种方式是效率比较高的定义单例方法,不仅能有效解决性能问题,还能解决线程安全问题,个人比较推荐这种,代码如下:

java设计模式-单例模式

以上是5种比较典型的定义单例模式的方法,当然还可以通过枚举、注册式方式等实现单例。