java中13个原子操作类

jdk1.5开始提供java.util.concurrent.atomic包下的原子操作类,基本采用的是unsafe实现的包装类

Atomic 包里一共提供了 13 个类,属于 4 种类型的原子更新方式,分别是原子更新基本类型、原子更新数组、原子更新引用和原子更新属性(字段)

原子更新基本类型

  1. AtomicBoolean //原子更新布尔类型
  2. AtomicInteger //原子更新整型
  3. AtomicLong //原子更新长整型
    AtomicInteger 中的常用方法
    ⚫int addAndGet(int delta):以原子方式将输入的数值与实例中的值
    (AtomicInteger 里的 value)相加,并返回结果。
    ⚫boolean compareAndSet(int expect,int update):如果输入的数值等于预期值,
    则以原子方式将该值设置为输入的值。
    ⚫ int getAndIncrement():以原子方式将当前值加 1,注意,这里返回的是自增前的
    值。采用的是CAS算法
public final int getAndIncrement() {
	 for (; ; ) {
		 int current = get();// get方法采用的是native getIntVolatile(),保证元素值的可见性
		 int next = current + 1;
		 if (compareAndSet(current, next)) return current;
	 }
	 
}
public final boolean compareAndSet(int expect, int update) {
 	return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

jdk 1.8采用的是getAndAddInt方法

    public final int getAndAddInt(Object var1, long valueOffset, int var4) {
        int var5;
        do {
            var5 = unsafe.getIntVolatile(var1, valueOffset);
        } while(!unsafe.compareAndSwapInt(var1, valueOffset, var5, var5 + var4));

        return var5;
    }

原子更新数组

  1. AtomicIntegerArray
  2. AtomicLongArray
  3. AtomicReferenceArray // 原子更新引用类型数组里的元素。
    AtomicIntegerArray中常用的方法有
    ⚫int addAndGet(int i,int delta):以原子方式将输入值与数组中索引 i 的元素相加。
    ⚫boolean compareAndSet(int i,int expect,int update):如果当前值等于预期值,则以原子方式将数组位置 i 的元素设置成 update 值。
    public static void main(String[] args) {
        int a[]  = new int[]{1,2};

        AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(a);
        atomicIntegerArray.getAndSet(0,3);

        System.out.println(atomicIntegerArray.get(0));
        System.out.println(a[0]);
    }

输出结果为:

3
1

AtomicIntegerArray 构建是建立在普通数组之上,重新复制新的数组,不改变原来普通数组的值

原子更新引用类型

  1. AtomicReference
  2. AtomicReferenceFieldUpdater // 原子更新引用类型里的字段
  3. AtomicMarkableReference // 原子更新带有标记位的引用类型
    AtomicReference为例:
public class AtomicReferenceTest {
    public static AtomicReference<User> atomicReference = new AtomicReference<>();

    public static void main(String[] args) {
        User xiaozhang = new User("xiaozhang", 5);
        atomicReference.set(xiaozhang);
        atomicReference.compareAndSet(xiaozhang,new User("zhangsan",8));

        System.out.println(atomicReference.get().getName());
        System.out.println(atomicReference.get().getAge());
    }

    static class User{
        private String name;
        private int age;

        public User() {
        }

        public User(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public int getAge() {
            return age;
        }
    }
}

输出结果:

zhangsan
8

原子更新字段类

  1. AtomicIntegerFieldUpdater:原子更新整型的字段的更新器。
  2. AtomicLongFieldUpdater:原子更新长整型字段的更新器。
  3. AtomicStampedReference:原子更新带有版本号的引用类型。该类将整数值与引用关联起来,可用于原子的更新数据和数据的版本号,可以解决使用 CAS 进行原子更新时可能出现的 ABA 问题。

AstomicIntegerFieldUpdater为例:
第一步:使用静态方法newUpdater()创建一个更新器,并设置想要更新的类和属性
第二步:更新类的字段必须使用public volatile修饰

public class AtomicReferenceTest {
    public static AtomicIntegerFieldUpdater<User> a = AtomicIntegerFieldUpdater.newUpdater(User.class,"age");

    public static void main(String[] args) {
        User xiaozhang = new User("xiaozhang", 5);
        // 实现年龄+1
        a.getAndIncrement(xiaozhang);
        System.out.println(a.get(xiaozhang));
    }

    static class User{
        private String name;
        // 此处要声明为 public volatile
        public volatile int age;

        public User() {
        }

        public User(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public int getAge() {
            return age;
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

木子Link

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

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

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

打赏作者

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

抵扣说明:

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

余额充值