软件体系结构-单例模式

定义

确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例。

  • 某个类只能有一个实例(private static)
  • 必须自行创建这个实例(私有构造方法)
  • 必须向整个系统提供这个实例(public getInstance)

UML

单例模式的几种写法

饿汉式单例

1
2
//在类被加载时就创建
private static Singleton instance = new Singleton();

懒汉式单例

1
2
3
4
5
6
7
8
9
//在被引用时才加载
private static Singleton instance = null;

public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}

懒汉式与双重检查锁定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class DoubleLockSingleton {
private volatile static DoubleLockSingleton instance;

private DoubleLockSingleton(){}

public static DoubleLockSingleton getInstance(){
//第一重判断
if(instance == null){
//锁定代码块
synchronized (DoubleLockSingleton.class){
//第二重判断
if(instance == null){
instance = new DoubleLockSingleton();
}
}
}
return instance;
}
}

静态内部类实现单例(Java最好的实现方式)

1
2
3
4
5
6
7
8
9
10
11
12
public class IoDHSingleton {
private IoDHSingleton(){}

//静态内部类
private static class HolderClass{
private final static IoDHSingleton instance = new IoDHSingleton();
}

public static IoDHSingleton getInstance(){
return HolderClass.instance;
}
}

枚举类实现单例模式

饿汉与懒汉:

  • 饿汉:无须考虑多个线程同时访问的问题;调用速度和反应时间优于懒汉式单例;资源利用效率不及懒汉式单例;系统加载时间可能会比较长
  • 懒汉:实现了延迟加载;必须处理好多个线程同时访问的问题;需通过双重检查锁定等机制进行控制,将导致系统性能受到一定影响

优点

  • 提供了对唯一实例的受控访问
  • 可以节约系统资源,提高系统的性能
  • 允许可变数目的实例(多例类)

缺点

  • 扩展困难(缺少抽象层)
  • 单例类的职责过重
  • 由于自动垃圾回收机制,可能会导致共享的单例对象的状态丢失

适用

  • 系统只需要一个实例对象,或者因为资源消耗太大而只允许创建一个对象
  • 客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例