解决ABA问题,原子引用

解决ABA问题,原子引用

整体思想是乐观锁。

一般的实现乐观锁的方式就是记录数据版本。

img 线程在提交前,根据版本号来判断是否冲突。

看代码:

package com.cc.cas;

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

public class CASDemo {

    static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(1,1);

    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();
            }

            System.out.println(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();

    }
}

运行结果:

A1=>1
B1=>1
true
A2=>2
true
A3=>3
false
B2=>3

可看到最后false,B2获得的版本号为3了,通过版本号知道值被线程A改过。

这里要注意一个问题:

AtomicStampedReference,如果泛型是包装类,注意对象的引用。

Integer 使用了对象缓存机制,默认范围是 -128 ~ 127 ,推荐使用静态工厂方法 valueOf 获取对象实例,而不是new,因为 valueOf 使用缓存,而 new 一定会创建新的对象分配新的内存空间;
在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值