LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 227|回复: 0

原子更新基本类型

[复制链接]
发表于 2024-1-17 17:41:23 | 显示全部楼层 |阅读模式

使用原子的方式更新基本类型,Atomic包提供了以下3个类。AtomicBoolean: 原子更新布尔类型。AtomicInteger: 原子更新整型。AtomicLong: 原子更新长整型。以上3个类提供的方法几乎一模一样,可以参考上面AtomicInteger中的相关方法。# 原子更新数组通过原子的方式更新数组里的某个元素,Atomic包提供了以下的3个类:AtomicIntegerArray: 原子更新整型数组里的元素。AtomicLongArray: 原子更新长整型数组里的元素。AtomicReferenceArray: 原子更新引用类型数组里的元素。这三个类的最常用的方法是如下两个方法:get(int index):获取索引为index的元素值。compareAndSet(int i,E expect,E update): 如果当前值等于预期值,则以原子方式将数组位置i的元素设置为update值。举个AtomicIntegerArray例子:import java.util.concurrent.atomic.AtomicIntegerArray;
public class Demo5 {
    public static void main(String[] args) throws InterruptedException {
        AtomicIntegerArray array = new AtomicIntegerArray(new int[] { 0, 0 });
        System.out.println(array);
        System.out.println(array.getAndAdd(1, 2));
        System.out.println(array);
    }
}
输出结果:[0, 0]
0
[0, 2]
# 原子更新引用类型Atomic包提供了以下三个类:AtomicReference: 原子更新引用类型。AtomicStampedReference: 原子更新引用类型, 内部使用Pair来存储元素值及其版本号。AtomicMarkableReferce: 原子更新带有标记位的引用类型。这三个类提供的方法都差不多,首先构造一个引用对象,然后把引用对象set进Atomic类,然后调用compareAndSet等一些方法去进行原子操作,原理都是基于Unsafe实现,但AtomicReferenceFieldUpdater略有不同,更新的字段必须用volatile修饰。举个AtomicReference例子:
import java.util.concurrent.atomic.AtomicReference;

public class AtomicReferenceTest {
   
    public static void main(String[] args){

        // 创建两个Person对象,它们的id分别是101和102。
        Person p1 = new Person(101);
        Person p2 = new Person(102);
        // 新建AtomicReference对象,初始化它的值为p1对象
        AtomicReference ar = new AtomicReference(p1);
        // 通过CAS设置ar。如果ar的值为p1的话,则将其设置为p2。
        ar.compareAndSet(p1, p2);

        Person p3 = (Person)ar.get();
        System.out.println("p3 is "+p3);
        System.out.println("p3.equals(p1)="+p3.equals(p1));
    }
}

class Person {
    volatile long id;
    public Person(long id) {
        this.id = id;
    }
    public String toString() {
        return "id:"+id;
    }
}
结果输出:p3 is id:102
p3.equals(p1)=false
结果说明:新建AtomicReference对象ar时,将它初始化为p1。紧接着,通过CAS函数对它进行设置。如果ar的值为p1的话,则将其设置为p2。最后,获取ar对应的对象,并打印结果。p3.equals(p1)的结果为false,这是因为Person并没有覆盖equals()方法,而是采用继承自Object.java的equals()方法;而Object.java中的equals()实际上是调用"=="去比较两个对象,即比较两个对象的地址是否相等。

原文链接:https://pdai.tech/md/java/thread/java-thread-x-juc-AtomicInteger.html

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表