• 微信公众号:美女很有趣。 工作之余,放松一下,关注即送10G+美女照片!

单例设计模式的实现

开发技术 开发技术 2周前 (05-04) 6次浏览

什么是单例设计模式

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

 

单例设计模式的作用

1.目的: 保证一个类仅有一个实例,并提供一个访问它的全局访问点。

2.解决的问题: 一个全局使用的类频繁地创建与销毁。

3.什么时候使用: 当您想控制实例数目,节省系统资源的时候。

 

单例设计模式的实现步骤

1.将构造方法私有化,使其不能在类的外部通过new关键字实例化该类对象

2.在该类内部产生一个唯一的实例化对象,并且将其封装为private static类型的成员变量。

3.定义一个静态方法返回这个唯一对象。

 

饿汉单例设计模式就是使用类的时候已经将对象创建完毕,不管以后会不会使用到该实例化对象,先创建了再说。很着急的样子,故被称为“饿汉模式”。

我们先来写一个单例设计模式 — 饿汉式

 单例设计模式的实现

 

 

 第二步可以用public修饰通过类名.instance去拿,不需要写第三步,但是这样不太好,正常一般是通过get方法去拿,这样更符合我们编程的思维。

下面我们来通过多线程来测试一下我们的单例

我们开一百条线程创建一千次对象来看看

单例设计模式的实现

 

 

 可以证明这种模式是没有问题的,它是最简单的单例设计模式,其实说白了它不是通过代码保证的单例,是通过虚拟机类加载器去保证的,因为加了静态(static)让它只执行一次。但是这样有一点不好,它一上来就把instance给new出来了,所有我们还有另一种方法,我们什么时候用什么时候new,我们看看第二个单例设计模式–“懒汉式”。

先写一个错误思路的分析一下

单例设计模式的实现

 

 

 第一次执行的时候new一个对象返回,第二次执行的时候又new了一个对象返回,我们如果不new对象instance去赋值的话instance里面存的是一个null,  我们需要第一次执行new一个对象返回,第二次执行不new对象直接返回,这里我们需要判断一下instance是否为null

单例设计模式的实现

 

 

 我们来测试一下

单例设计模式的实现

 

 

 多线程情况下执行getInstance()的时候,任何一个地方都有可能抢走执行权。比如第一个线程刚走到判断instance是否为null,执行权被抢走了,另外一个线程走进来判断instance也是为null,这里它们就null了两次对象

 为了效果更加明显,我们让它睡一会儿

单例设计模式的实现

 

 单例设计模式的实现

 

这时候我们来加锁将共享数据(instance)锁起来,来个同步方法synchronized。

单例设计模式的实现

 

 单例设计模式的实现

以上就是单例设计模式“饿汉式”和“懒汉式”,但是这两种都有自己的小弊端。

饿汉式:没有实现懒加载,一上来就new对象

懒汉式:懒汉式有锁,每一次getInstance()都需要获取锁对象,执行完了再去释放锁对象,效率低且比较浪费资源,我们应该让它尽量的少获取锁释放锁

 

双重检查机制:

这个可以说是单例模式终极的模式,这里我就不画图了,直接看代码。

单例设计模式的实现

 

 

 

大家可以看到这里做了两次判断,第一次判断从逻辑上来讲是为了不使用同步,留下了第一次获取对象的线程,但是第一次进来了很多条线程开始抢了怎么办,使用锁让第一次进来的线程排队,一个一个执行,第二个判断让只有第一次强到执行权的线程看到instance==null,把对象new出来以后,第二条线程过来instance不为null了,就不会new对象,直接返回。

但是这样会出现指令重排序的问题,需要在声明上加关键字volatile,这样我们的new对象就是一步完成的了,我们来看不加volatile对象是怎么创建的。

单例设计模式的实现

 

 

正常我们new对象是1-2-3完成的,但是会出现指令重排序是1-3-2步完成,一般情况下是没有问题的,就好比问服务员要一杯水,她把杯子拿过来给你倒水或者倒了水再把杯子给你,但是在单例多线程情况下,第一条线程进来已经赋值了,底层正在进行初始化,第一条线程此时已经执行完了,这时候另一个线程进来了,发现对象已经赋值了要拿来用,但是对象正处于半初始化状态不能用,就会出现问题,所以需要加上volatile保证不会出现半初始化状态的对象。

单例设计模式的实现

 


程序员灯塔
转载请注明原文链接:单例设计模式的实现
喜欢 (0)