确保某个类有且只有一个对象实例存在,避免产生多个对象消耗过多的资源。
实现单例模式主要有几个关键点:
1.构造函数不对外开放,一般为private
2.通过一个静态方法或枚举返回一个单例对象
3.确保单例类的对象有且只有一个,尤其是在多线程环境下
4.确保单例类对象在反序列化时不会重新构建对象
饿汉式:
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
这是最简单的方法,在类引用的时候就会实例化。不能延迟加载,某种意义上会增加系统的负载。
懒汉式:
public class Singleton {
private static Singleton instance = null;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
在饿汉法的基础上增加了延迟加载,只有调用getInstance的方法才会实例化对象,在单线程中没有问题,但在多线程中有可能导致多次实例化。
多线程安全性兼顾效率(双重检查锁 Double Check Lock)DCL 实现实例:
public class Singleton {
private static Singleton instance = null;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
DCL方式实现单例模式的优点是既能够在需要时才初始化单例,又能够保证线程的安全性,且单例对象初始化后调用getInstance不进行同步锁。
本方法的亮点都在getInstance上,方法中对instance进行了两次判空,第一次判空主要是为了避免不必要的同步,第二次则是为了在null的情况下创建实例。