1.定义
保证一个类仅有一个实例,并提供一个全局的访问点。
2.优点
在内存里只有一个实例,减少了内存开销。设置全局的访问点,严格控制访问。
3.代码示例
(1).饿汉式(静态常量)
public class Singleton {
private final static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}
(2).懒汉式(线程不安全)
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
//存在多个线程竞争的情况
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
(3).双重检查
public class Singleton {
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;
}
}
为什么使用双重检查?
1.保障线程安全
2.弥补懒汉式线程安全但效率低的缺陷
为什么使用volatile?
1.新建对象实际上有3个步骤,创建一个空对象,调用构造函数初始化,将实例传给对象引用
2.重排序会带来空指针异常,需要防止重排序