CAS compareAndSet:比较并交换,ABA问题

CAS会产生ABA问题(使用别人动过的值,但不知情)

package VolatileA;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * CAS compareAndSet:比较并交换
 * 会产生ABA问题(使用别人动过的值,但不知情)
 *
 * @author liu
 */
public class CompareAndSetA {
    public static void main(String[] args) {
        //期望、更新
        //public final boolean compareAndSet(int expect, int update)
        //如果达到期望值,那么就更新,否则不更新
        AtomicInteger atomicInteger = new AtomicInteger(2020);

        //--------------被人动过的代码-----------------
        atomicInteger.compareAndSet(2020, 2021);
        atomicInteger.compareAndSet(2021, 2020);
        System.out.println(atomicInteger.get());


        //-------自己期望的代码------------
        System.out.println(atomicInteger.compareAndSet(2020, 666));
        System.out.println(atomicInteger);
    }
}

乐观锁原理解决ABA问题

package CAS;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * @author liu
 */
public class CASDemo {
    
    //AtomicStampedReference  注意,如果泛型是一个包装类,注意引用对象问题
    //正常业务,都是比较一个个对象
    static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(1, 1);

    //CAS compareAndSet :比较并交换!
    public static void main(String[] args) {
        new Thread(() -> {
            int stamp = atomicStampedReference.getStamp();//获取版本号
            System.out.println("a1->" + stamp);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            atomicStampedReference.compareAndSet(1, 2, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1);
            System.out.println("a2->" + atomicStampedReference.getStamp());
            System.out.println(atomicStampedReference.compareAndSet(2, 1, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1));
            System.out.println("a3->" + atomicStampedReference.getStamp());
        }, "a").start();


//乐观锁的原理相同
        new Thread(() -> {
            int stamp = atomicStampedReference.getStamp();
            System.out.println("b1->" + stamp);
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(atomicStampedReference.compareAndSet(1, 6, stamp, stamp + 1));

            System.out.println("b2->" + atomicStampedReference.getStamp());

        }, "b").start();
    }
}

posted @   小幼虫虫  阅读(235)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示