【juc学习之路第5天】引用原子类和属性修改器

6 篇文章 0 订阅

引用原子类

包含三种:

  • AtomicReference: 引用类型原子类。实现原理:CAS。

compareAndSet():无法通过匿名对象进行比较,因为比较的内容是地址而不是Obejct.equals()

  • AtomicStampedReference: 带有引用版本号的原子类。实现原理:CAS同时C版本号。

compareAndSet():比较内容地址的同时对版本号做出比较。

  • AtomicMarkableReference: 带有标记的引用原子类。实现原理:CAS同时C标记。

compareAndSet():比较内容地址的同时对标记做出比较。

public class Main {
    public static void main(String[] args) throws Exception {
        Person birdy = new Person("birdy");
        AtomicReference<Person> atomicRef = new AtomicReference<>(birdy);
        atomicRef.compareAndSet(birdy, new Person("alexander")); // success
        atomicRef.compareAndSet(new Person("birdy"), new Person("alexander")); // false

        AtomicStampedReference<Person> stampedRef = new AtomicStampedReference<>(birdy, 1);
        stampedRef.compareAndSet(birdy, new Person("alexander"), 1, 2);

        AtomicMarkableReference<Person> markRef = new AtomicMarkableReference<>(birdy, true);
        markRef.compareAndSet(birdy, new Person("alexander"), true, false);
    }
}

解决的问题

AtomicStampedReferenceAtomicMarkableReference共同解决多线程下访问数据操作ABA不同步的问题(即:两个线程并发操作,由于更新不同步导致更新错误。对应应用:Github代码提交)

属性修改器

在类中需要原子地get/set某个属性,可以使用属性修改器。包含三种:

  • AtomicIntegerFiledUpdater: 原子整型成员修改器
  • AtomicLongFieldUpdater: 原子长整型成员修改器
  • AtomicReferenceFieldUpdater: 原子引用成员修改器

针对AtomicLongFieldUpdater分析,它的构造是protected的,它有一个入口静态方法:newUpdater()

newUpdater()

@CallerSensitive
public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass,String fieldName) {
    Class<?> caller = Reflection.getCallerClass();
    if (AtomicLong.VM_SUPPORTS_LONG_CAS)
      	return new CASUpdater<U>(tclass, fieldName, caller);
    else
      	return new LockedUpdater<U>(tclass, fieldName, caller);
}

发现有两种更新器:

  • CASUpdater: 通过CAS机制实现更新。
  • LockedUpdater: 通过锁定两块长整型地址修改属性,用于x32环境。

使用方法

class Person {
    private String name;
    private volatile long balance; // 必须使用volatile定义Updater操作的成员
    private static final AtomicLongFieldUpdater<Person> UPDATER =
            AtomicLongFieldUpdater.newUpdater(Person.class, "balance");

    public long getBalance() {
        return UPDATER.get(this);
    }
    public void setBalance(long balance) {
        UPDATER.set(this, balance);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

edanhuang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值