Eglusaxie 2021-04-16 01:02 采纳率: 100%
浏览 41
已采纳

以下关于Atomic和volatile的理解是否正确

public class DoubleCheckVolatile {
    private volatile static DoubleCheckVolatile doubleCheckVolatile;

    public static DoubleCheckVolatile getDoubleCheckVolatile() {
        if (doubleCheckVolatile != null)
            return doubleCheckVolatile;
        synchronized (DoubleCheckVolatile.class) {
            if (doubleCheckVolatile != null)
                return doubleCheckVolatile;
            synchronized (DoubleCheckVolatile.class) {
                doubleCheckVolatile = new DoubleCheckVolatile();
                return doubleCheckVolatile;
            }
        }
    }

    private DoubleCheckVolatile() {
    }
}



public class DoubleCheckAtomic {
    private static AtomicReference<DoubleCheckAtomic> doubleCheckAtomicAtomicRef = new AtomicReference<>();

    public static DoubleCheckAtomic getDoubleCheckAtomic() {
        if (doubleCheckAtomicAtomicRef.get() != null)
            return doubleCheckAtomicAtomicRef.get();
        synchronized (DoubleCheckAtomic.class) {
            if (doubleCheckAtomicAtomicRef.get() != null)
                return doubleCheckAtomicAtomicRef.get();
            synchronized (DoubleCheckAtomic.class) {
                doubleCheckAtomicAtomicRef.set(new DoubleCheckAtomic());
                return doubleCheckAtomicAtomicRef.get();
            }
        }
    }

    private DoubleCheckAtomic() {
    }
}

这两个类的做法是否能都能防止对象初始化步骤被指令重排后导致的并发危险?

  • 写回答

1条回答 默认 最新

  • 心灵彼岸-诗和远方 2021-04-16 10:06
    关注

    并发主要解决三个问题,CPU切换线程执导致的原子性问题缓存导致的可见性问题,指令优化导致的重排序问题

    原子类解决的是原子性问题,volatile解决的是变量可见性、禁止重排序;所以你这可以解决指令重排序,但是写的有些繁琐,一般写法如下:

    public class DoubleCheckVolatile {
        private volatile static DoubleCheckVolatile doubleCheckVolatile;
     
        public static DoubleCheckVolatile getDoubleCheckVolatile() {
            if (doubleCheckVolatile == null) {
                synchronized (DoubleCheckVolatile.class) {
                    if (doubleCheckVolatile == null) {
                        doubleCheckVolatile = new DoubleCheckVolatile();
                    }
                }
            }
        }
     
        private DoubleCheckVolatile() {
        }
    }
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料