概述
原文地址:http://mp.weixin.qq.com/s/eL2UsxkzsiWWvTKlqZyc6w
正常的单例模式:
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同步锁来保证线程同步
class Singleton {
private static Singleton instance;
public synchronized static Singleton function getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance
}
}
问题:同步问题得到解决,但是效率低。
解决:直接在方法上加synchronized,导致所有的情况都会锁住方法,其实我们只需要在instance为null,即初始化实例的时候才会发生同步问题,所以修改加锁方式。
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关键字禁止指令重排
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来保证同步,避免多线程问题
class Singleton {
private class innerClass {
public static Singleton instance = new Singleton();
}
public static Singleton function getInstance() {
return innerClass.instance
}
}
2.枚举类型
public enum EnumFoctory {
singleFoctory;
private Singleton instance;
private EnumFoctory() {
instance = new Singleton;
}
public Singleton getInstance() {
return instance;
}
}
- 静态代码块,功能与内置静态类一样,
问题: 加载时机无法控制
初始化依赖其他操作,无法保证准备好
class Singleton {
private static Singleton instance;
static {
instance = new Singleton();
}
public static Singleton function getInstance() {
return innerClass.instance;
}
}
最后
以上就是霸气爆米花为你收集整理的高并发下的单例模式的全部内容,希望文章能够帮你解决高并发下的单例模式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复