Solo  当前访客:0 开始使用

使用枚举类创建线程安全的单例

单例模式是Java常用的一种设计模式,常见的有“饿汉”、“懒汉”模式。然而他们都有各自的缺点,本文所描述的是一种线程安全且不会被反射所破坏的单例创建方式。

饿汉模式创建单例

public class Singleton {
    private static final Singleton instance = new Singleton();

    private Singleton(){
        // 初始化操作
    }

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

饿汉模式使用了static关键字,只有一个静态实例,保证了线程安全。但是我们初始化的时候加载了这个类,如果永远不调用getInstance方法,就会导致资源的浪费。

懒汉模式创建单例

public class Singleton {
    private static Singleton instance; // 这里没有new一个对象

    private Singleton(){
	// 初始化操作
    }

    public static Singleton getInstance(){
        if (instance == null) // 多个线程进入会创建多个实例
            instance = new Singleton();
        return instance;
    }
}

懒汉模式解决了资源浪费的问题,但是如果在并发情况下多个线程经过 if (instance == null),会导致出现多份实例的情况。这种情况,我们大多会使用synchronized来同步该方法解决,可是加锁后,多个线程执行的时候,只有抢到锁的线程才允许进入方法,而其余线程等待,系统的性能不高。

枚举类创建单例

public enum JedisEnum {
    @SuppressWarnings("unused") JEDIS;

    private JedisPool jedisPool;

    JedisEnum() {
        jedisPool = new JedisPool(new JedisPoolConfig(), "127.0.0.1", 6379);
    }

    public JedisPool getJedisPool() {
        return jedisPool;
    }
}

以JedisPool的单例为例
由于枚举类是线程安全的,而且只会被加载一次,使得枚举类创建单例天生就具有线程安全的特性。而且也不会被反射破坏单例。

尾巴

懒汉模式可以使用volatile关键字+双重校验保证单例,但是存在反射破坏单例的情况,所以我个人提倡使用枚举类。


标题:使用枚举类创建线程安全的单例
作者:wellCh4n
地址:http://www.wellch4n.com/articles/2019/09/04/1567576338971.html