java设计模式-单例模式

一.什么是单例模式

在平时开发中使用某个类的实例时,直接使用new即可创建一个对象,试想一下当你如果频繁使用某个实例对象时,就会耗费更多的资源,就好像请了一个保姆,需要保姆帮你干一些事,如:洗衣服,拖地,扫地等等。每次需要保姆的时候就直接吩咐就行,不需要重新聘请一个。在实际很多开发场景中,都需要用到单例模式:如访问IO和数据库等资源,其中在Android开发中出色的图片加载框架ImageLoader就使用了单例模式,ImageLoader中有线程池,缓存系统,网络请求等等,是非常消耗资源的,如果每加载一张图片就新建一个ImageLoader的实例时不合理的,因此采用了单例模式,以让一个应用程序中有且仅有ImageLoader实例。

二.单例模式的定义

一个类有且仅有一个实例,并且自行实例化向整个系统提供

1.单例类保证只有一个实例

2.单例必须自己创建自己的唯一实例

3.单例类提供给系统该唯一实例

三.实践

1.饿汉式

java设计模式-单例模式_第1张图片

从代码可以看出,外面只能从Singleton.getInstance()获得Singleton的实例,并且这个实例时静态对象,一声明就已经初始化了,保证了Singleton对象的唯一性,是线程安全的,但是也有弊端,假如我一开始不需要Singleton这个对象,但是一开始就已经创建对象了,那么能不能再程序需要的时候在创建对象呢,显然意见是有的。

2.懒汉式

java设计模式-单例模式_第2张图片

同理将构造函数私有化,对外提供Singleton.getInstance()方法获得Singleton的实例,不一样的是饿汉式一开始就已经初始化实例了,而懒汉式只有调用Singleton.getInstance()才去创建Single的实例对象,同时在Singleton.getInstance()方法加了一个synchronizes的关键字,这个关键字其实是用来避免多线程共同来调用这个对象。,但是每次调用的时候用这个锁来保证线程安全造成了很多不必要的开销。因为上锁就要开锁,因此有没有更好的方法呢?

改进版

java设计模式-单例模式_第3张图片

这样避免了假如入同时多个线程同时创建实例对象的问题,但是这种方法和在方法上加synchronized同步锁是没有区别的。因为下一个线程想要获得对象必须等待上一个线程释放锁后才能继续运行。

3.双重校验锁

java设计模式-单例模式_第4张图片

使用双重检查进一步优化,由方法锁变成代码块锁,避免了整个方法被锁,提高执行效率。也同时优化懒汉式改进版的优点,即避免两个或多个线程同时进入第一个判空如果有对象还继续创建对象的问题。

4.静态内部类

java设计模式-单例模式_第5张图片

静态内部类保证了单例在多线程并发下的线程安全性,当外部类被加载时,静态内部类是不会被加载的,所以成员变量也不会被初始化,当只有调用getInstance()时才会被加载,并且代码简洁易懂。静态内部类但是在遇到序列化对象时,运行得到的结果还是多例的。

5.内部枚举类

java设计模式-单例模式_第6张图片

上诉可以通过EnumSingleton.Singleton获取单例,然后再调用内部的方法 枚举的优点:对象实例的创建时线程安全的,防止反射创建多个实例和没有序列化问题。以上就是基本的单例模式的实现,希望所有开发者一起学习和进步~

你可能感兴趣的:(java设计模式-单例模式)