单件模式——HeadFirst设计模式学习笔记

时间:2022-12-26 09:59:24

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

特点:

  • 单例模式确保一个实例被创建,并且任意时刻都只有一个对象。
  • 特征是构造函数为私有,然后声明一个私有静态成员作为类对象,对外提供一个静态类方法创建该对象
  • 在创建对象时会先判断是否已经创建,若是则直接返回已经创建的对象,若没有则创建新对象

用途:

  • 某些对象在程序运行过程中我们只需要一个,或只能生成一个,如线程池、注册表和代表打印机的对象等。如果创建多个实例就会发生异常。
  • 如果将对象赋给某个全局变量(急切初始化),即事先就建立好对象,若对象在本次程序执行没有使用且占用很多资源就不是很合适

注意:

  • 即使正确创建了单件模式类,但当使用多个类加载器时,每个类加载器定义了各自的命名空间,当不同的类加载器加载了同一个类,从整体程序上看,同一个类就会被加载多次,造成多个单件的存在。解决办法:自行指定同一个类加载器
  • 单件类不能被继承,因为构造方法是私有的,如果这的把构造器的权限改变了,想要让子类能够顺利工作,基类必须实现注册表功能。即创建对应Map<String(class.name), instance>,用来记录类是否被创建以及被创建的实例 
  • 多线程问题:当有多个变成并发执行时,可能无法保证单件。解决办法:只要把getInstance()变成同步(synchronized)方法
  • 并发与性能问题:解决:使用双重加锁检验机制,先检验是否创建,如未创建再同步(代码如下)

代码实现:

 1 public class Singleton { 
 2     private volatile static Singleton uniqueInstance;//volatile 确保当uniqueInstance初始化为Singleton的实例时,多个线程可以正确的处理uniqueInstance变量。 
 3     private Singleton() {} 
 4     public static Singleton getInstance() { 
 5         if (uniqueInstance == null) {//只有第一次才会执行这里面的代码。也就是说第一次为同步,后来就是不作为了——这就是我们要的效果。 
 6             synchronized (Singleton.class) { 
 7                 if (uniqueInstance == null) { 
 8                     uniqueInstance = new Singleton(); 
 9                 } 
10             } 
11         } 
12         return uniqueInstance; 
13     } 
14 }