• java内存模型与volatile变量与Atomic的compareAndSet


    java分主内存和工作内存, 主内存是线程共享的, 工作内存是每个线程独有的. java对主内存的操作是通过工作内存间接完成的: 先拷贝主内存变量值到工作内存, 在工作内存操作这个变量的副本, 完成后将这个副本的值再写回主内存. 这几个操作不是原子性的, 意味着当有多个线程同时想修改主内存的话, 在某个线程返回变量副本之前, 主内存的值相对于这个线程获得的主内存的值已经发生, 那么基于旧值得操作必然是错误的. 这就是java并发问题的根本原因.

    8种基本原子操作(个人理解):

    lock

    unlock   锁操作

    read  将主内存的值拷贝到高速缓存

    load  将高速缓存的值拷贝到工作内存副本

    use   将工作内存副本值拷贝到运算寄存器

    assign 将运算寄存器的值拷贝到工作内存副本

    store  将工作内存副本的值拷贝到高速缓存

    write  将高速缓存的值写回主内存

    多线程对一个变量的操作, 只有当后6个操作是同时进行的, 没有被其他线程打断, 才是线程安全的.

    volatile保证read load use同时执行, 但对assign store write不保证, 所以对volatile变量的并发修改是线程不安全的, 如i++.

    atomic类的核心就是对volatile变量的compareAndSet操作, 个人理解是用volatile保证到寄存器中以供计算的值是正确的, compareAndSet应该是保证从计算开始到write回主内存这几个操作是同时进行的(直接操作原生内存,不用C库和JVM之间的拷贝), 这样就保证了并发安全性, 同时避免了使用锁. 如果在这两个阶段之间变量在内存中的值被改变, 则cas失败, 所以cas修改变量值一般放在循环中无限尝试直到成功

  • 相关阅读:
    SpringBoot项目中,表单的验证操作
    微信点餐系统(十)-卖家端通用功能和上下架
    IDEA中Springboot静态文件加载(热部署)
    微信点餐系统(九)-卖家端订单
    微信点餐系统(八)-微信支付与退款
    MyBatis的生命周期
    关于flexjson将json转为javabean的使用
    Spring MVC中前端控制器拦截问题
    springmvc实现文件上传
    springmvc拦截器实现用户登录权限验证
  • 原文地址:https://www.cnblogs.com/bianzy/p/6558808.html
Copyright © 2020-2023  润新知