dubbo源码volatile使用问题
最近看了一些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("<dubbo:reference interface=\"\" /> 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("<dubbo:reference interface=\"\" /> interface not allow null!");
}
// 获取消费者全局配置
checkDefault();
appendProperties(this);
if (getGeneric() == null && getConsumer() != null) {
setGeneric(getConsumer().getGeneric());
}
.................