天天见的单例模式了解一下

24 篇文章 3 订阅

参考链接如下:
为什么要使用单例模式
Java单例模式的5种实现方法
为何Java单例模式我只推荐两种

单例模式那些坑

这篇内容主要是自己看完网友写的博客之后的一点点总结。

为什么要用 ?

保证仅有一个实例对象。

单例模式和静态方法区别

  • 从面向对象来说,静态方法就和实例对象没有太多的关系,比如工具类;
  • 从功能上来说,单例模式可以继承、实现,可以进行有意义的派生。可以保证单个实例对象。

那怎么去实现 ?

第二个问题的答案 ,具体可以看开头的推荐的第二篇博客。这里还需要知道单例模式实现的几个共同点:

  • 私有的构造函数,对外无法实例化;
  • 由于外部无法实例化,但是还是需要调用呀,那所以要提供给一个能获取单例类的实例对象的方法啊。一般该方法的名字 : createInstance() ;
  • createInstance() 返回的值 一般都是私有静态的 。 确保所以调用者调用的都是同一个单例对象嘛。

每种实现方式的优缺点在哪?

这里附上一张自己画的思维图,方便记忆吧。
在这里插入图片描述
这里还要补充两点的是:

(1)上述的几种方法中,应该除了枚举类型的方式之外,都可以通过反射或者序列化等方式进行构造。所以,从某个角度来说,也不是单例模式。
正因此,百度知道了对应的文章推荐最佳实践是使用枚举类型

那如果我想说,我就不想使用枚举单例模式呢?没办法了么?
哈哈,有人提供了解决办法,看文首的【单例模式那些坑】博客, 不得不佩服都是高手在人间呐~

高能警告: 这种在构造函数里抛出异常的补救办法,只能 针对 饿汉式 !!!
在这里插入图片描述

(2)双重校验为什么在synchronized 之后又判null了一次?
在这里插入图片描述
假设现有线程A和线程B都去争夺Singleton.class的对象锁,线程A先成功获取锁,线程B被挂起等待锁释放。线程A判断instance为null,然后进行了new ,执行完之后释放了对象锁。这时候线程B拿到了锁,如果这里不进行instance的判null操作,那么线程B又进行一次对象的构造。这样会导致实例除了多个对象哦。

日常推荐哪种方式呢

在这里插入图片描述
日常推荐:双重检查模式 、静态内部类模式。
高手过招:枚举单例模式。

单例模式有什么问题么?

要回答这个问题,我们首先回忆一下GC的垃圾回收机制,垃圾回收分为三代,如果类中包含静态成员,垃圾回收机制是不会回收的,也就意味着如果我们无节制的使用单例,会造成程序运行过程中出现大量的实例不会被销毁,会无意识的造成内存使用增高。 如果采用懒加载的方式,在单例未被调用的时候,不会实例化,如果采用饿汉加载的话,那么在程序初始化的时候,就会被初始化,无疑会加重程序的初始化成本,增加启动时间。

单例模式和静态方法各自适合什么场景?

在这里插入图片描述

单例模式常用的场景有哪些

  • 资源开销大的线程池、数据库连接池等,
  • 系统运行时的一些配置和参数。这些配置是公共的,存在于整个生命周期的。如果每次需要就new一个,明显是浪费内存,所以这种也可以使用单例模式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值