前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >多线程情况下的单例模式(双重校验锁+volatile)

多线程情况下的单例模式(双重校验锁+volatile)

作者头像
名字是乱打的
发布2022-05-13 12:43:44
4960
发布2022-05-13 12:43:44
举报
文章被收录于专栏:软件工程

标准写法:双重校验锁+volatile

代码语言:javascript
复制
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;  
    }  
}

private volatile static Singleton singleton; //volatile 保证单例变量前后不发生指令重排优化 点击链接查看为什么要用volatile在这里禁止指令重排,禁止的是哪里可能的重排?

代码语言:javascript
复制
memory = allocate();  // 1:分配对象的内存空间
ctorInstance(memory); // 2:初始化对象
instance = memory;  // 3:设置instance指向刚分配的内存地址

根源在于代码中的2和3之间,可能会被重排序。例如:

代码语言:javascript
复制
memory = allocate();  // 1:分配对象的内存空间
instance = memory;  // 3:设置instance指向刚分配的内存地址
// 注意,此时对象还没有被初始化!
ctorInstance(memory); // 2:初始化对象

我们判断该对象是否存在的时候是判断该对象有没有指向刚分配的内存地址,如果分配了就认为其不为null,如果我们先执行3再执行2,可能第一个线程刚执行3,第二个线程进来判断外层singleton不为null就直接返回一个还没初始化的对象去使用导致报错.

Singleton getSingleton() 不直接加synchroized锁而是先校验一次后再加锁,这样可以保证该单例具有较高的性能

Singleton为什么设置为static?我们需要提供一个公有的静态方法,将创建的对象返回。 单例类因为不允许其他程序用new来创建该类对象,所以只能将单例类中的方法定义成静态的(随类的加载而加载),静态方法不能访问非静态的成员,故只能将该类中new的本类对象变成静态的。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档