《HeadFirst设计模式》第五章单件模式-读书笔记

By | 2019年10月21日

《HeadFirst设计模式》第五章单件模式-读书笔记

案例代码链接:https://github.com/rainweb521/My-tutorial/tree/master/Design_patterns

1. 什么是单件

在我们的系统中,有一些对象其实我们只需要一个,比如说:线程池、缓存、对话框、注册表、日志对象、充当打印机、显卡等设备驱动程序的对象。事实上,这一类对象只能有一个实例,如果制造出多个实例就可能会导致一些问题的产生,比如:程序的行为异常、资源使用过量、或者不一致性的结果。

使用单例模式的好处:

  • 对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销;
  • 由于 new 操作的次数减少,因而对系统内存的使用频率也会降低,这将减轻 GC 压力,缩短 GC 停顿时间。

2.spring中的单件模式

Spring 中 bean 的默认作用域就是 singleton(单例)的。 除了 singleton 作用域,Spring 中 bean 还有下面几种作用域:

  • prototype : 每次请求都会创建一个新的 bean 实例。
  • request : 每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效。
  • session : 每一次HTTP请求都会产生一个新的 bean,该bean仅在当前 HTTP session 内有效。
  • global-session: 全局session作用域,仅仅在基于portlet的web应用中才有意义,Spring5已经没有了。Portlet是能够生成语义代码(例如:HTML)片段的小型Java Web插件。它们基于portlet容器,可以像servlet一样处理HTTP请求。但是,与 servlet 不同,每个 portlet 都有不同的会话

3.经典的单件模式

4.设计模式

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

5.改善多线程

5.1使用synchronized

同步会降低性能,只有第一次执行此方法时,才真正需要同步。换句话说,一旦设置好 uniquelnstance变量,就不再需要同步这个方法了。之后每次调用这个方法,同步都是一种累赘。

如果你的应用程序可以接受 getlnstance造成的额外负担,就忘了这件事吧。同步 getinstance的方法既简单又有效。但是你必须知道,同步一个方法可能造成程序执行效率下降100倍。因此,如果将 getinstance的程序使用在频繁运行的地方,你可能就得重新考虑了。

5.2使用”急切”创建实例,而不用延迟实例化的做法

如果应用程序总是创建并使用单件实例,或者在创建和运行时方面的负担不太繁重,你可能想要急切( eagerly)创建此单件,如下所示。

利用这个做法,我们依赖JVM在加载这个类时马上创建此唯一的单件实例。JWM保证在任何线程访问 uniquelnstancei静态变量之前,一定先创建此实例。

5.3“双重检查加锁”,在 getinstance()中少使用同步

利用双重检查加锁( double- checked locking),首先检査是否实例已经创建了,如果尚未创建,“オ”进行同步。这样一来,只有第一次会同步,这正是我们想要的。

如果性能是你关心的重点,那么这个做法可以帮你大大地减少 getlnstanceo的时间耗费。

发表评论

电子邮件地址不会被公开。 必填项已用*标注