定义
确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。单例模式是一种对象创建型模式。
UML类图
代码实现
饿汉式
EagerSingleton.java
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
public static EagerSingleton getInstance() {
return instance;
}
private EagerSingleton() {
}
}
懒汉式线程不安全
LazySingleton.java
public class LazySingleton {
private static LazySingleton sInstance = null;
public static LazySingleton getInstance() {
if (sInstance == null) {
sInstance = new LazySingleton();
}
return sInstance;
}
private LazySingleton() {
}
}
懒汉式线程安全
LazySingleton.java
public class LazySingleton {
private static LazySingleton sInstance = null;
public static synchronized LazySingleton getInstance() {
if (sInstance == null) {
sInstance = new LazySingleton();
}
return sInstance;
}
private LazySingleton() {
}
}
懒汉式双重检查锁定
LazySingleton.java
public class LazySingleton {
private volatile static LazySingleton sInstance = null;
public static LazySingleton getInstance() {
if (sInstance == null) {
synchronized (LazySingleton.class) {
if (sInstance == null) {
sInstance = new LazySingleton();
}
}
}
return sInstance;
}
private LazySingleton() {
}
}
静态内部类方式
StaticHolderSingleton.java
public class StaticHolderSingleton {
public static class HolderClass {
public static final StaticHolderSingleton sInstance = new StaticHolderSingleton();
}
public static StaticHolderSingleton getInstance() {
return HolderClass.sInstance;
}
private StaticHolderSingleton() {
}
}
优缺点
主要优点
-
单例模式提供了对唯一实例的受控访问。因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它。
-
由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模式无疑可以提高系统的性能。
-
允许可变数目的实例。基于单例模式我们可以进行扩展,使用与单例控制相似的方法来获得指定个数的对象实例,既节省系统资源,又解决了单例单例对象共享过多有损性能的问题。
主要缺点
-
由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。
-
单例类的职责过重,在一定程度上违背了“单一职责原则”。因为单例类既充当了工厂角色,提供了工厂方法,同时又充当了产品角色,包含一些业务方法,将产品的创建和产品的本身的功能融合到一起。
-
现在很多面向对象语言(如Java、C#)的运行环境都提供了自动垃圾回收的技术,因此,如果实例化的共享对象长时间不被利用,系统会认为它是垃圾,会自动销毁并回收资源,下次利用时又将重新实例化,这将导致共享的单例对象状态的丢失。