设计模式——使用枚举实现单例模式

工作中常用的 6 种设计模式
之前见到公司代码中的

DomainCfg domainCfg = MdmCommandFactory.INSTANCE.getDomain(domain);

来获取Domaincfg对象,感觉哪里怪怪的,一直没去看,今天有时间去研究了一波。

网上的单例模式已经讲了很多,特别是双重检测锁实现单例模式已经有很多文章分析了。
但是枚举方式都是一笔带过,平时也没怎么去看,今天记录一下。

首先对比双重校验实现

public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    if (singleton == null) {  
        synchronized (Singleton.class) {  
        if (singleton == null) {  
            singleton = new Singleton();  
        }  
        }  
    }  
    return singleton;  
    }  
}  

枚举实现

public enum Singleton {  
    INSTANCE;  
    public void whateverMethod() {  
    }  
} 

显然枚举代码简洁的不止一点点
优点1:

使用非枚举的方式实现单例,都要自己来保证线程安全,所以,这就导致其他方法必然是比较臃肿的。
而我们定义的一个枚举,在第一次被真正用到的时候,会被虚拟机加载并初始化,而这个初始化过程是线程安全的。而我们知道,解决单例的并发问题,主要解决的就是初始化过程中的线程安全问题。
所以,由于枚举的以上特性,枚举实现的单例是天生线程安全的。

优点2:

普通的Java类的反序列化过程中,会通过反射调用类的默认构造函数来初始化对象。所以,即使单例中构造函数是私有的,也会被反射给破坏掉。由于反序列化后的对象是重新new出来的,所以这就破坏了单例。
但是,枚举的反序列化并不是通过反射实现的。所以,也就不会发生由于反序列化导致的单例破坏问题。

所以,用枚举实现单例简单方便。举个获取用户的例子

public enum ObjFactory {
    /**
     * 单例
     */
    INSTANCE;

    private Map<String, User> userCfg = new ConcurrentHashMap<>();

    ObjFactory() {
        loadx();
    }

    private void loadx() {
        loadXX1();
        loadXX2();
    }
    private void loadXX2() {
    }
    private void loadXX1() {
        userCfg.put("boss",new User()
                .setName("悠哈")
                .setAge(3)
                .setEmail("111@qq.com"));
    }

    public User getUser(String key){
        User user = userCfg.get(key);
        return user;
    }




}
    @Test
    void test003(){
        User user1 = ObjFactory.INSTANCE.getUser("boss");
        User user2 = ObjFactory.INSTANCE.getUser("boss");
        System.out.println(user1==user2);
    }

相关文章
为什么我墙裂建议大家使用枚举来实现单例。
Java枚举实现单例模式原理
深度分析Java的枚举类型—-枚举的线程安全性及序列化问题 - 风动静泉 - 博客园 (cnblogs.com)

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值