定义
- 确保类只有一个实例,通过自行实例化后向整个系统提供这个单一实例
UML类图

七种常见的单例模式
class Singleton_lazy {
private static Singleton_lazy mInstance;
private Singleton_lazy() {
}
public static Singleton_lazy getInstance() {
if (mInstance == null) {
mInstance = new Singleton_lazy();
}
return mInstance;
}
}
- 2.线程安全的懒汉式
- 特点:在获取单例的方法上加synchronized关键字保证线程安全,但每次获取都加锁效率比较低
class Singleton_lazySync {
private static Singleton_lazySync mInstance;
private Singleton_lazySync() {
}
public static synchronized Singleton_lazySync getInstance() {
if (mInstance == null) {
mInstance = new Singleton_lazySync();
}
return mInstance;
}
}
- 3.双重校验锁DCL(double check lock)
public class Singleton_DCL {
private static volatile Singleton_DCL mInstance;
private Singleton_DCL() {
}
public static Singleton_DCL getInstance() {
if (mInstance == null) {
synchronized (Singleton_DCL.class) {
if (mInstance == null) {
mInstance = new Singleton_DCL();
}
}
}
return mInstance;
}
}
class Singleton_hungry {
private static final Singleton_hungry mInstance = new Singleton_hungry();
private Singleton_hungry() {
System.out.println("构造器");
}
public static Singleton_hungry getInstance() {
return mInstance;
}
public static void main(String[] args) {
System.out.println("main");
Singleton_hungry instance =Singleton_hungry.getInstance();
}
}
class Singleton_staticInnerClass {
private Singleton_staticInnerClass() {
System.out.println("构造器");
}
public static Singleton_staticInnerClass getInstance() {
return SingletonHolder.mInstance;
}
private static class SingletonHolder {
public static final Singleton_staticInnerClass mInstance = new Singleton_staticInnerClass();
}
public static void main(String[] args) {
System.out.println("main");
Singleton_staticInnerClass instance =Singleton_staticInnerClass.getInstance();
}
}
- 6.枚举
- 特点:简单,可读性差,而且Android不推荐使用枚举(加大内存占用)
class Singleton_enum {
public static void main(String[] args) {
SingleTon singleTon = SingleTon.INSTANCE;
}
enum SingleTon {
INSTANCE
}
}
- 7.容器类
- 特点:可统一管理多种单例类,降低了用户的使用成本,也对用户隐藏了具体实现,降低了耦合度
public class Singleton_map {
private static Map<String, Object> mObjMap = new ConcurrentHashMap<>();
private Singleton_map() {
}
public static void addInstance(String key, Object instance) {
if (!mObjMap.containsKey(key)) {
mObjMap.put(key, instance);
}
}
public static Object getInstance(String key) {
return mObjMap.get(key);
}
}
使用场景与应用举例
- 使用场景
- 确保某个类有且仅有一个对象的场景,避免产生多个对象消耗过多的资源,或者某种类型的对象在当前环境中有且只有一个
- 应用举例
- 全局的用户类
- 访问IO、数据库等操作使用单例管理类,防止系统消耗资源过多
优缺点
- 优点
- 全局只有一个实例,减少内存开支,减少系统的性能开销
- 避免对资源的多重利用,例如写文件操作,单一实例避免同一文件的同时写操作
- 设置单一实例可共享资源空间
- 缺点
- 单例模式通常没有接口,扩展需要修改封装的单例类代码,扩展比较困难
- 单例如果持有非Application级别的全局context,容易造成内存泄露