定义
确保一个类只有一个实例,并提供一个全局访问点
Ensure a class only has one instance, and provide a global point of access to it.
使用场景
- 必须只有一个类的一个实例,并且它必须可以从公知的接入点访问客户端
- 当单个实例应该通过子类化扩展时,客户端应该能够使用扩展实例而不修改它们的代码
典型使用场景
- 日志类
- 数据库连接
- 文件管理器
例子
一个经典的单例:
public class Singleton{
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
考虑到多线程:
// 1. synchronized 性能差
public class Singleton{
private static Singleton instance;
private Singleton(){}
// synchronized可以确保只能有一个线程进入下面的程序
public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
// 2. 急切创建实例,而不用延迟实例化的做法
public class Singleton{
// JVM加载这个类时马上创建此唯一的单件实例
private static Singleton instance = new Singleton();
private Singleton(){}
public static synchronized Singleton getInstance(){
return instance;
}
}
// 3. 双重检查加锁 在getInstance()中减少使用同步
public class Singleton{
// Volatile确保多线程正确地处理instance
private Volatile static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){ // 检查实例,如果不存在,就进入同步区域
synchronized (Singleton.class) { // 只有第一次才彻底执行这里的代码
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}