招聘预算网站怎么做,徐州网站制作报价,易语言做购物网站,适合seo软件CAS(compare and swap) CAS是#xff08;compare and swap#xff09;的缩写#xff0c;字面意思是比较交换。CAS锁通常也是实现乐观锁的一种机制#xff0c;首先会给它一个期望值#xff0c;用期望值与老值做比较#xff0c;如果相等就用新传入的值进行修改。但是CAS通常…CAS(compare and swap) CAS是compare and swap的缩写字面意思是比较交换。CAS锁通常也是实现乐观锁的一种机制首先会给它一个期望值用期望值与老值做比较如果相等就用新传入的值进行修改。但是CAS通常有一个ABA问题就是你把新值与老值做比较的时候可能有其他线程已经修改过这个值了只是后来最后值又被修改了回来通常解决办法是用原子包装类的戳记引用的版本号机制修改一次版本号也会发生自增最后修改值的时候就会有期望值和期望版本号都得符合不然修改失败。 ABA问题的复现及解决
package com.bilibili.juc.cas;import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;/*** CAS是CompareAndSwap的简称 期望值与老值比对如果一致把新值覆盖但是会有一个问题就是别的线程把值修改后再次修改为了原来的值所以就加入版本号机制* 常用来实现乐观锁* AtomicStampedReference 戳记引用 在执行 CAS 操作时不仅比较引用的值是否相同还会比较一个标记值Stamp。只有当引用值和标记值都相同时* 才会执行 CAS 操作。这样可以避免 ABA 问题因为即使引用的值在过程中变化了但如果标记值也变化了CAS 操作就不会成功。*/
public class ABADemo {static AtomicInteger atomicInteger new AtomicInteger(100);static AtomicStampedReferenceInteger stampedReference new AtomicStampedReference(100, 1);public static void main(String[] args) {new Thread(() - {int stamp stampedReference.getStamp();System.out.println(Thread.currentThread().getName() \t 首次版本号 stamp);//暂停500毫秒,保证后面的t4线程初始化拿到的版本号和我一样try {TimeUnit.MILLISECONDS.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}stampedReference.compareAndSet(100, 101, stampedReference.getStamp(), stampedReference.getStamp() 1);System.out.println(Thread.currentThread().getName() \t 2次流水号 stampedReference.getStamp());stampedReference.compareAndSet(101, 100, stampedReference.getStamp(), stampedReference.getStamp() 1);System.out.println(Thread.currentThread().getName() \t 3次流水号 stampedReference.getStamp());}, t3).start();new Thread(() - {int stamp stampedReference.getStamp();System.out.println(Thread.currentThread().getName() \t 首次版本号 stamp);//暂停1秒钟线程,等待上面的t3线程发生了ABA问题try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}boolean b stampedReference.compareAndSet(100, 2022, stamp, stamp 1);System.out.println(由于戳记标识被t3修改了所以修改结果为 b 值为 stampedReference.getReference() ;戳记版本标识为 stampedReference.getStamp());}, t4).start();}/*** 下面就是复现ABA问题*/private static void abaHappen() {new Thread(() - {atomicInteger.compareAndSet(100, 101);try {TimeUnit.MILLISECONDS.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}atomicInteger.compareAndSet(101, 100);}, t1).start();new Thread(() - {try {TimeUnit.MILLISECONDS.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(atomicInteger.compareAndSet(100, 2022) \t atomicInteger.get());}, t2).start();}
}