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() {
        }
    }
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 Android STD快速启动
  • ¥15 如何使用simulink建立一个永磁同步直线电机模型?
  • ¥30 天体光谱图的的绘制并得到星表
  • ¥15 PointNet++的onnx模型只能使用一次
  • ¥20 西南科技大学数字信号处理
  • ¥15 有两个非常“自以为是”烦人的问题急期待大家解决!
  • ¥30 STM32 INMP441无法读取数据
  • ¥15 R语言绘制密度图,一个密度曲线内fill不同颜色如何实现
  • ¥100 求汇川机器人IRCB300控制器和示教器同版本升级固件文件升级包
  • ¥15 用visualstudio2022创建vue项目后无法启动