单例模式

定义

保证某个类在全局只有一个实例存在。

代码实现

饿汉模式

class Singleton {
    private static Singleton sInstance = new Singleton();

    //私有构造方法
    private Singleton() {
        
    }

    public static Singleton getInstance() {
        return sInstance;
    }
}

借助类加载机制避免了多线程重复创建实例问题,类加载时就进行初始化,没有实现懒加载。

懒汉模式(线程不安全)

class Singleton {
    private static Singleton sInstance;

    //私有构造方法
    private Singleton() {
        
    }

    public static Singleton getInstance() {
        if (sInstance == null) {
            //多个线程进入判断会创建不同的实例
            sInstance = new Singleton();
        }
        return sInstance;
    }
}

实现了延迟初始化,但是多线程访问会重复创建实例。

懒汉模式(互斥锁)

class Singleton {
    private static Singleton sInstance;

    //私有构造方法
    private Singleton() {
        
    }

    //使用 synchronized 保证互斥
    public static synchronized Singleton getInstance() {
        if (sInstance == null) {
            sInstance = new Singleton();
        }
        return sInstance;
    }
}

使用互斥锁避免的并发问题,但是由于每次获取实例都要加锁(大部分情况不需要这么做),导致性能较低。

懒汉模式(双重null检查)

class Singleton {
    private static volatile Singleton sInstance;

    // 私有构造方法
    private Singleton() {

    }

    public static Singleton getInstance() {
        if (sInstance == null) {
            //如果多个线程进入判断,通过加锁保证互斥
            synchronized (Singleton.class) {
                if (sInstance == null) {
                    sInstance = new Singleton();
                }
            }
        }
        return sInstance;
    }
}

既避免了并发问题,又避免了互斥锁写法带来的性能问题。

通过 volatile 关键字保证可见性。

静态内部类

class Singleton {
    // 私有构造方法
    private Singleton() {
    }

    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
}

只有调用getInstance()方法时才会加载静态内部类并创建静态常量,所以实现了延迟加载;通过类加载机制避免了多线程并发问题。

Last updated

Was this helpful?