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());
        }
        .................
        
posted @ 2015-12-04 17:43  hellopretty  阅读(379)  评论(0编辑  收藏  举报