CAS(Compare And Swap)
CAS的思想:
CAS的全写是 Compare And Swap, 意思是比较并交换。
CAS实现同步的思想是:
1)首先对两个值进行比较;
2)当两个值相等,则进行值的更新。
看完CAS后,我感到很疑惑。
**疑惑点:**
1)CAS中做比较的两个值是什么?是指向储存位置的地址值?还是值本身?
2)CAS做比较的两个值来自哪块内存区域?
3)CAS进行值的更新后,新值来自哪里?
首先来看程序运行时的Java内存分配:
1.进程:当一个进程运行时,Java虚拟机会为进程分配内存(其中的堆内存区是线程共享区)。
2.线程:同一个进程中,Java虚拟机又会为每一个线程分配私有的内存区
(私有内存区包括:虚拟机栈、本地方法栈等)
CAS实现解读:
1.在Java虚拟机中,对于进程A:
Java虚拟机首先为进程A分配一块内存区,进程A又将所得到的的内存区分为:
1) 线程共享内存区(堆内存等);
2) 线程私有内存区(虚拟机栈、本地方法栈等),每个线程有自己单打的私有内存区.
(1) 虚拟机栈:线程a通过虚拟机栈来实现对进程A当中共享堆内存区中数据的的调用;
(2) 本地方法栈:本地方法栈则存储了线程a中的局部变量、操作数栈等数据信息.
2.线程a对进程A共享内存区中的共享数据的调用:
2.1 线程a通过虚拟机栈调用存储于进程A的堆内存中的dataPosition位置的数据dataOld
2.2 线程a对进程堆内存中的dataOld数据进行拷贝,
拷贝完成后, 在线程a私有的内存区拥有dataOld数据的一份拷贝dataCopy.
2.3 在线程a私有的内存区中, 线程a对dataCopy进行操作,
得到了对dataCopy操作后的新值dataNew(说明dataCopy发生了变化).
2.4 线程a执行CAS:
1) CAS操作中包含三个元素: CAS(dataPosition, dataCopy, dataNew)
2) 寻找原值:
首先, 根据dataPosition地址值,
去进程A堆内存中, 找到存储于dataPosition位置的dataOld值;
3) 比较(比较拷贝值和原值):
找到dataOld后, 将dataCopy和dataOld进行比较:
(1) 当dataOld和dataCopy相同时:
说明, 线程a操作后得到dataNew和进程A中的dataOld不同步;
此时, 就将存储于dataPosition位置的dataOld更新为dataNew,
进而使线程a和进程A在dataPosition内存位置上的值实现同步.
(2) 如果dataOld和dataCopy不相同时:
说明, dataPosition位置的dataOld已经被更新过了(但是这个更新不一定是更新为当前的dataNew, 这是另外一个多线程并发问题, 这里不细说)
至此, 解答了对CAS的三个初始疑惑。
总结:
理解CAS要明白几个点:
1) CAS是对单个线程来说的。
单个线程对数据进行更新操作后,通过CAS实现将进程共享区的数据旧值更新为操作后的值。
2) CAS实现的是进程共享堆内存的数据和线程私有栈内存的数据的同步。
3) CAS完成同步需要三个要素:
(1) dataOld值在进程共享区中的内存位置dataPosition,
(2) dataOld值在单个线程中的拷贝值dataCopy,
(3) 和单个线程对dataOld值进行操作后得到的新值dataNew
4) CAS中当共享内存位置dataPosition中的dataOld值和线程中的拷贝值dataCopy相等时,
将共享内存位置dataPosition中的dataOld值更新为dataNew值
说明:
初次学习并发相关的内容知识, 在理解上, 可能存在诸多不足。