| 关键词: 线程 安全 懒汉 部类 一般 优点 缺点 双重 推荐 | |||||||||||||||||||||||||||||||||||||||||
第一种:饿 汉方式
优点:代码简单易读,由JVM类加载机制保证了线程安全,无需业务方关心。 缺点:无法做到延迟创建对象,在加载class的时候就会创建对象。 第二种:懒汉方式(线程不安全)
优点:代码简单易读。 缺点:在多线程情况下非现场安全,可能出现创建多个实例。 第三种:懒汉方式(线程安全)
优点:代码简单易读,线程安全。 缺点:每次调用时,都需要线程同步,性能较差。 第四种:内部类方式
优点:由JVM保证线程安全,不需要业务方关心。 缺点:第一次访问可能较慢,他需要加载内部类这样可能占用更多的code区域的内存。 第五种:枚举
枚举在单例上的使用较其他有点不太一样,使用示例如下: Singleton.INSTANCE.doSomeThing();优点:由JVM保证了线程安全,代码简洁。 缺点:代码不易理解。 Joshua Bloch大神较为推崇这种写法,他在《Effective Java》中明确表达过下面观点: 使用枚举实现单例的方法虽然还没有广泛采用,但是单元素的枚举类型已经成为实现Singleton的最佳方法。 第六种:双重校验锁
优点:线程安全 缺点:每次访问对象都需要判null,并且volatile导致每次都会访问主内存,性能相比较而言较差。 该单例模式较容易出错,特别是volatile关键字要加,具体原因可以参考: Java面试官最喜欢问的关键字-volatile 总结
具体选择哪种方式肯定是具体场景具体分析;但是一般情况下,我是比较推荐恶汉和枚举方式。 大家如果阅读过JDK源码可能就会注意到,JDK主要采用的恶汉和懒汉模式,基本上不会采用枚举、双重校验锁;我猜测可能的原因双重双重校验锁再JDK1.5版本之前有问题并且枚举是在JDK1.5版本才引用的,导致历史上很多JDK在实现单例模式没有那么多选择。 其他很多开源项目在选择单例上就较为丰富,基本上每种单例都可能遇到,比如在Hystrix就遇到了恶汉模式(HystrixTimer)和内部类(HystrixPlugins) 。 | |||||||||||||||||||||||||||||||||||||||||
| 本文出处: https://www.tuicool.com/articles/AJBzMbu | |||||||||||||||||||||||||||||||||||||||||
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|