设计模式读书笔记(四)

"Head First 设计模式第五章"

Posted by jhljx on January 29, 2018

目录

1. 单件模式

单件模式

常用单件模式的实例:

比如,线程池(threadpool),缓存(cache),对话框,处理偏好设置和注册表(registry)的对象。

单件模式的实例常用来管理共享的资源,比如数据库连接或线程池。

单件模式的定义

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

利用延迟实例化的方式创建单件,这种做法对资源敏感的对象特别重要。

单件模式的优点

单件可以==延迟实例化==

在多线程同时调用getInstance()方法时会导致出错,可能出现两个实例。如果给该方法加上synchronized关键字设置同步,的确可以解决多线程问题,但是实际上只是在第一次执行该方法时需要同步,后续只需要return就好了。此外,同步会减低程序性能,同步可能使一个程序的执行效率下降100倍。

两种选择

  • 如果getInstance()的性能对应用程序不是很关键,就什么都别做,直接用synchronized关键字就可以了
  • 使用“急切”创建实例,而不用延迟实例化的做法

    public class Singleton { private static Singleton uniqueInstance = new Singleton();

      private Singleton() {}
        
      private static Singleton getInstance() {
          return uniqueInstance;
      }   }
    

在静态初始化器(static initializer)中创建单件,且保证了线程安全(thread safe)。利用该做法,JVM保证了在任何线程访问uniqueInstance静态变量之前,一定先创建此实例。

  • 用“双重检查加锁”,在getInstance()中减少使用同步

利用双重检查加锁(double-checked locking),首选检查是否实例已经创建了,如果尚未创建,“才”进行同步。这样一来,只会有一次同步。该方法适用于Java 5以上的版本。

private class Singleton {
    private volatile static Singleton uniqueInstance;
    
    private Singleton() {}
    
    public static Singleton getInstance() {
        if (uniqueInstance == null) {  //只有第一次才会彻底执行这里的代码
            synchronized (Singleton.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }
    
}

单件模式的目的:确保类只有一个实例并提供全局访问。而全局变量可以提供全局访问,但是不能保证只有一个实例。