我是靠谱客的博主 霸气爆米花,这篇文章主要介绍高并发下的单例模式,现在分享给大家,希望可以做个参考。

原文地址:http://mp.weixin.qq.com/s/eL2UsxkzsiWWvTKlqZyc6w
正常的单例模式:

复制代码
1
2
3
4
5
6
7
8
9
class Singleton { private static Singleton instance; public static Singleton function getInstance() { if (instance == null) { instance = new Singleton(); } return instance } }

问题:线程A判断完是否null,执行new之前,线程B判断是否null结果是true,所以线程B也会进来new一个对象,导致单例模式失败。

解决:为了防止多线程访问,使用synchronized同步锁来保证线程同步

复制代码
1
2
3
4
5
6
7
8
9
class Singleton { private static Singleton instance; public synchronized static Singleton function getInstance() { if (instance == null) { instance = new Singleton(); } return instance } }

问题:同步问题得到解决,但是效率低。

解决:直接在方法上加synchronized,导致所有的情况都会锁住方法,其实我们只需要在instance为null,即初始化实例的时候才会发生同步问题,所以修改加锁方式。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
class Singleton { private Singleton instance; public static Singleton function getInstance() { if (instance == null) { synchronized(this) { if (instance == null) { instance = new Singleton(); } } } return instance } }

这样就是在instance为null的情况下才加锁,减少加锁的概率,提高性能。
问题:指令重排,引起线程A的instance未完成初始化,线程B就发现instance不为null而引发错误。

解决:volatile关键字禁止指令重排

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
class Singleton { private static volatile Singleton instance; public static Singleton function getInstance() { if (instance == null) { synchronized(this) { if (instance == null) { instance = new Singleton(); } } } return instance } }

基本上双检查锁机制已经能满足大部分场景的需求,但是还有其他更独特的方式解决单例问题。
1. 内置静态类, 类加载的由加载器执行,由JVM来保证同步,避免多线程问题

复制代码
1
2
3
4
5
6
7
8
class Singleton { private class innerClass { public static Singleton instance = new Singleton(); } public static Singleton function getInstance() { return innerClass.instance } }

2.枚举类型

复制代码
1
2
3
4
5
6
7
8
9
10
public enum EnumFoctory { singleFoctory; private Singleton instance; private EnumFoctory() { instance = new Singleton; } public Singleton getInstance() { return instance; } }
  1. 静态代码块,功能与内置静态类一样,
    问题: 加载时机无法控制
    初始化依赖其他操作,无法保证准备好
复制代码
1
2
3
4
5
6
7
8
9
class Singleton { private static Singleton instance; static { instance = new Singleton(); } public static Singleton function getInstance() { return innerClass.instance; } }

最后

以上就是霸气爆米花最近收集整理的关于高并发下的单例模式的全部内容,更多相关高并发下内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部