锁的原子性

 

 

 

 

 

 

乐观锁,自旋锁 无锁 cas    从CPU读取数据内存 值v  假如是0  修改为1
然后往回写  以前需要上锁 但是乐观锁不上锁了 
在往回写的过程中判断 若内存中的数据依然为0  那么就没有线程修改 把0改成1
若其他线程修改  那么在往回写的过程中 会发现线程已经修改 已经不是0了
那么 就继续读取内存中修改的值 然后再加1 在往回写 然后继续判断是否是之前修改后的值
若不是继续次操作  直到和原来读取的值相同

若是在 判断的过程中 内存数据被修改了,然后又被其他线程给修改回来了 那么会产生ABA问题 其他线程修改次数最后值和原值相同 时就需要加版本号v 一种是时间戳 或者布尔类型
当CPU读完内存的数据后 往内存中写的时候 是CAS操作 compare and swap
比较这个数据是否还是原来的数据  如果是 设置新的值 
但是这里是两步骤  很有可能被其他线程将目前内存的值修改  
原来的线程 就将其他线程修改的值又改会自己设定的值  那么其他线程修改的值就被覆盖了

如果要避免这种事情发生  那么 就必须保证CAS 操作时原子性的
但是乐观锁在底层上还是一种悲观锁
cmpxchg 不是原子指令 
所以需要加上lock 来锁住 缓存和cpu的数据总线  不能让其他cpu 来对其进行修改

 

 

 

 

在ThreadA解锁之后  会把所有的内存状态和本地的缓存做一个刷新  来确保一致性
然后下一个ThreadB才能继续
sys 底层会有lock指令 有屏障的作用来保证顺序执行(这里的顺序执行时ThreadA和threadB 但是并不会保证threadA里面的顺序)

所以说sys是保证可见性的

 

posted @ 2022-04-26 13:11  花心大萝卜li  阅读(74)  评论(0)    收藏  举报