23种设计模式--单例模式
创建型设计模式的一种
【DP】定义
保证一个类仅有一个实例,并提供一个访问他的全局访问点。
使用场景
- 需要全局唯一,并维护某个全局变量
- 避免对象重复创建,减少内存空间占用
实现
懒汉模式—非线程安全
1 | public class Singleton { |
核心是:instance和构造方法要私有,getInstance方法要是静态的。
懒汉模式(使用Double-Check Locking)—线程安全
1 | public class Singleton { |
核心是: 两次判空和synchronized的同步。
两次判空的目的是:当instance存在时,就直接返回。当instance为null时,如果有两个线程同时调用getInstance()方法,他们都会通过第一个if判断,然后会进入加锁的临界区,第一个线程进入后,执行完instance已经有值了,然后第二个线程进入临界区,如果没有第二个if语句,会导致instance会被重新实例化,导致instance不是单例了。
懒汉模式(静态内部类)—线程安全
1 | public class Singleton { |
核心是: LazyLoader必须是private和static修饰,保证只有Singleton调用。
这种方式是懒加载模式,只有调用1
2
3
4
5
6
7
8
9
10
#### 饿汉模式---线程安全
```Java
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
在类初始化的时候就会初始化instance对象,由于又是final类型的,所以instance不会改变,保证内存中只有一个对象存在。
注意事项
- 尽量使用线程安全的方式实现
- Double-check Locking在使用中依然有问题,原因是在new Singleton()时jvm对字节码的重排序操作。修改方法是给instance增加volatile修饰符,volatile会增加内存屏障,防止重排序。具体可以看传统单例模式双重检查锁存在的问题.