博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
dubbo源码volatile使用问题
阅读量:4619 次
发布时间:2019-06-09

本文共 1345 字,大约阅读时间需要 4 分钟。

最近看了一些dubbo的源码,发现里边在使用volatile变量的时候有点问题,代码片段如下,其中initialized变量为volatile类型的boolean变量,这里的目的是想保证init()方法对于单个实例只调用一次,但是在多线程的情况下,完全有可能多个线程都走到if判断的逻辑而且同时还没有线程走到initialized=true,此时,多个线程就会全部都通过if判断,然后完成下边的初始化操作。

private void init() {         if (initialized) {            return;        }        initialized = true;        if (interfaceName == null || interfaceName.length() == 0) {            throw new IllegalStateException("
interface not allow null!"); } // 获取消费者全局配置 checkDefault(); appendProperties(this); if (getGeneric() == null && getConsumer() != null) { setGeneric(getConsumer().getGeneric()); } .................

这里主要的问题是volatile变量可以保证单步操作变量的原子性,但是不能保证先判断再赋值这种多步操作的原子性,修改后的代码如下:

//这里将initialized变量声明为AtomicBoolean类型 private void init() {        boolean flag = initialized.compareAndSet(false, true);        if (!flag) {            return;        }        if (interfaceName == null || interfaceName.length() == 0) {            throw new IllegalStateException("
interface not allow null!"); } // 获取消费者全局配置 checkDefault(); appendProperties(this); if (getGeneric() == null && getConsumer() != null) { setGeneric(getConsumer().getGeneric()); } .................

转载于:https://www.cnblogs.com/hellopretty/p/5020069.html

你可能感兴趣的文章
Convert,Parse,TryParse数据转换比较
查看>>
手把手教你如何安装Pycharm
查看>>
冲刺第七天
查看>>
2019 计蒜之道 初赛 第二场
查看>>
链表的倒数第k个节点
查看>>
JS中数组初始化以及赋值
查看>>
经典SQL查询语句大全
查看>>
Orchard Core 文档翻译 (二)代码生成模板 Code Generation Templates
查看>>
nginx日志格式配置
查看>>
Hashmap与Hashtable的区别及Hashmap的原理
查看>>
华硕A43系列笔记本卡解决办法
查看>>
树莓派进阶之路 (038) - P2P 文件下载机
查看>>
fedora 27
查看>>
SpringBoot框架
查看>>
python post与get请求的区别
查看>>
css确定取消 悬浮底部样式 和 金额 后缀
查看>>
NGUI制作流光效果
查看>>
lets encrypt与openssl结合实现双认证
查看>>
html5 03
查看>>
workon在zsh中不起作用
查看>>