本文最后更新于:2022年7月6日 下午
概览:单例模式、volatile
单例模式
类只需要有一个对象,不希望有更多的对象。
可以避免反复初始化和释放,这样会占用很多的资源,使用单例模式常驻内存可以节约资源。
单例模式与静态类的选择
- 不需要维护任何状态、仅全局访问,适用于静态类。
- 需要维持一些特定的状态,此时更适合使用单例模式。
饿汉式
1 2 3 4 5 6 7 8 9 10 11
| public class Singleton {
private static Singleton INSTANCE = new Singleton();
private Singleton(){ }
public static Singleton getInstance(){ return INSTANCE; } }
|
- 静态代码在被加载后就进行了初始化
- 天然的线程安全
- 但是没有起到延迟加载的效果。
懒汉式 - 线程安全
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 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; } }
|
- Double Ckeck Lock:防止获取到锁之后,覆盖已经被初始化的实例
- synchronized:加锁,保证只有一个线程能获取到锁
- volatile:保证可见性与有序性,防止指令重排。
静态类内部加载
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Singleton {
private Singleton(){ }
private static class LazyHolder{ private static final Singleton INSTANCE = new Singleton(); }
public Singleton getInstance(){ return LazyHolder.INSTANCE; } }
|
- 静态内部类不会在单例类加载的时候就加载,而是在调用getInstance()方法是被加载
- 线程安全的。