• Java-学习日记(Atomic,Volatile)


    很早之前在公司就看到了atomicInteger,atomicLong这些变量了,一直不明白是什么意思,今天花了点时间了解下。

    volatile:

    先从volatile开始讲起,volatile是多线程中会使用的关键字,volatile不加锁(即不会线程阻塞,但不安全),但保证了可见性(一个线程修改,立即刷新到主内存,对其他线程可见)和禁止指令重排序。但是这样依然对存在一个问题,就是多线程时候来不及刷新到主内存中,新线程就获取到了旧数据。例如下面代码:

    错误原因:有的线程已经把a进行了加1操作,但是还没来得及重新刷入到主存,其他的线程就重新读取了旧值。因为才造成了错误

    package atomic;
    
    import java.util.concurrent.atomic.AtomicInteger;
    
    /**
     * @ProjectName: AtomicIntegerTest
     * @Package: atomic
     * @Description:
     * @Author: huyuqiao
     * @CreateDate: 2020/9/21 14:25
     */
    //Volatile:无法保证最后a结果一定是50
    //AtomicInteger:虽然最后顺序不一样,但是最终a一定是50
    public class AtomicIntegerTest {
    //    private static volatile int a = 0;
        static AtomicInteger a = new AtomicInteger();
        public static void main(String[] args){  
            AtomicIntegerTest atomicIntegerTest = new AtomicIntegerTest();
            Thread[] threads = new Thread[5];
            for (int i = 0; i < 5; i++) {
                threads[i] = new Thread(() ->{
                    try{
                        for (int i1 = 0; i1 < 10; i1++) {
    //                        System.out.println(a++);
                            System.out.println(a.incrementAndGet());
                            Thread.sleep(500);
                        }
                    } catch (Exception e){
                        e.printStackTrace();
                    }
                });
                threads[i].start();
            }
        }
    }
    
    
    atomicInteger

    上面代码中atomicInteger却保证了数据的完整性,原因就在于内部CAS原理(compare and swap)

    CAS 即比较并替换,实现并发算法时常用到的一种技术。CAS操作包含三个操作数——内存位置、预期原值及新值。执行CAS操作的时候,将内存位置的值与预期原值比较,如果相匹配,那么处理器会自动将该位置值更新为新值,否则,处理器不做任何操作。

    但是这样会有一个ABA问题,就是虽然你保证了数据最终一定一直,但是无法保证数据中途会被修改,即ABA问题(变量A->B->A中途会被修改)

    ABA问题解决办法:解决使用AtomicStampReference.getstamp标记更新次数,若没被更新,则正确,否则报错。

    面试问题:并发编程(原子性、可见性、一致性)

  • 相关阅读:
    传的参数乱码
    Tp5.0中分页加搜索的用法!!!
    TP5.0循环更新数据问题
    TP5.0中foreach里面使用save方法变成更新问题
    TP5.0中软删除的用法
    TP5.0中save方法加主键id的用法!!!
    用宝塔的定时任务写shell命令会以root执行的解决方法
    兆易创新RISC-V开发板评测
    使用vsCode配合IAR搭建arm开发环境
    Vue 路由导航解析流程
  • 原文地址:https://www.cnblogs.com/meditation5201314/p/13707590.html
Copyright © 2020-2023  润新知