c++ map 多线程_线程安全原理简析及HashMap多线程并发5种场景异常分析

多线程并发出现异常的情况

单例模式

public class DoubleCheckSingleton {
     
    /**
     * 使用volatile,在多线程场景下,确保在判断null时,对所有线程可见
     */
    private static volatile DoubleCheckSingleton uniqInstance;
    /**
     * 构造器私有,防止外部实例化该类
     */
    private DoubleCheckSingleton() {}
    /**
     * 静态方法实例化,由于在类内部,可以调用构造器
     */
    public static DoubleCheckSingleton getInstance(){
        if (null == uniqInstance) { // 此处判断需要可见性volatile
            synchronized (DoubleCheckSingleton.class) {
                if (null == uniqInstance) {
                    //延迟初始化
                    uniqInstance = new DoubleCheckSingleton();
                }
            }
        }
        return uniqInstance;
    }
}

可见性

  • 引发原因

CPU高速缓存 由于各个线程会在执行是从 主存 加载到CPU高速缓存中执行,节省读取内存时间(CPU速度>> 主存速度)

0eefb586116d386c2cbfa10fa5ca7fca.png

线程A对共享变量V做了修改,其它线程B看到V的值还是之前的old失效数据

  • 后果(以单例模式举例)

失效数据

线程A已经创建了instance,但是线程B读取的instance还是null,会导致创建了两个instance,A和B拿到的实例不一样!!

失效值可能导致错误的结果或者导致活跃性问题。

  • fix方案

volatile

加锁(syn、lock)

有序性

  • 引发原因

编译优化之指令重排序

CPU执行指令时会有一些指令重排序以期最大效率

16504b7ea3ff429adfefb7547e5288d9.png
  • 后果(以单例模式举例)

单例模式赋值和实例化的重排序导致的异常

370923320e4753bbca273301084f62a8.png
  • fix方案

volatile

加锁

通过Happens-before规则实现

内置锁的释放锁操作发生在该锁随后的加锁操作之前

一个volatile变量的写操作发生在这个volatile变量随后的读操作之前

原子性

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值