目录
单件模式
常用单件模式的实例:
比如,线程池(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;
}
}
单件模式的目的:确保类只有一个实例并提供全局访问。而全局变量可以提供全局访问,但是不能保证只有一个实例。