个人对单例模式的理解

Posted yang457556017

tags:

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

问题:单例模式有什么用处?

有些对象我们只需要一个,比如说线程池,对话框,缓存,网站计数器,任务管理器,打印机,显卡等设备的驱动程序对象。这些对象只能有一个实例,如果制造出多个实例,就会导致许多问题产生,比如程序的异常行为,资源使用过量或者是不一致的结果等等。

解决方法:使用单例模式;

单例模式:确保一个类只有一个实例,并提供一个全局的访问点;

 

单例模式分类:

饱汉式:

技术分享图片

为什么叫饱汉式呢?因为他的实例不是在一开始就创建好的,我们可以看作他是饱的,不着急创建实例,在需要的时候才去创建;

饱汉式优点:

资源利用率高,不执行getInstance()就不会被实例,可以执行该类的其他静态方法;

饱汉式缺点:

线程不安全,第一次加载时不够快,多线程使用不必要的同步开销大;

 

 

饿汉式:

 技术分享图片

饿汉式我们就可以看成他很饿,急着创建实例,在JVM加载这个类的时候就创建好了这个实例;

饿汉式的优点:

1.线程安全 ;

2.在类加载的同时已经创建好一个静态对象,调用时反应速度快;

饿汉式缺点:

可能会浪费资源,如果一直没有调用getInstance方法,但执行该类的其他静态方法或者加载了该类(class.forName),那么这个实例仍然初始化;

 

饱汉式和饿汉式的区别就是两者创建实例的时间不同,饱汉式在需要的时候才去创建,饿汉式是一开始就创建好;

 

 

上面说到了饱汉式线程不安全,我们有没有办法让饱汉式安全呢?答案是肯定的;

方法一:只要把getInstance方法变为同步方法(synchronized)方法就可以避免线程安全的问题;

技术分享图片

但是方法一有个问题:同步会降低性能,有没有不降低性能又线程安全的方法,或者说减少同步的次数?这时候就要看方法二了;

 

方法二:使用“双重检查锁”,在getInstance中减少使用同步;

技术分享图片

双重检查锁也存在缺点:第一次加载时反应不快,由于java内存模型一些原因偶尔失败

 

 

总结:一般建议采用饿汉式,不建议采用饱汉式;

 

以上是关于个人对单例模式的理解的主要内容,如果未能解决你的问题,请参考以下文章

面试官:说说对单例模式的理解,最后的枚举实现我居然不知

(@WhiteTaken)设计模式学习——单例模式

序列化对单例模式的破坏

设计模式 - 单例模式(详解)看看和你理解的是否一样?

被面试官怼了之后我才发现,我几乎对单例模式一无所知!

单例模式 - Singleton Patterns