Concurrent——Atomic原子操作类

打算把Concurrent包下面的一些类整理一下。今天先从最简单的开始,Atomic原子类。

先看一下atomic包下的类
这里写图片描述
一共12个,共分四类:基本类型、数组、引用、属性。我们就按这四个分类,介绍一下它们的用途以及实现。

基本类型

包含上图红框里面的三个类。由于三个类提供的方法基本一致,下面以AtomicInterger为例。
AtomicInteger的常用方法如下:
这里写图片描述
实现逻辑都差不多,取当前值current,然后计算更改后的值。利用CAS思想,比较current和当前数值是否相等,如果相等,则更新,如果不相等,则重复上述操作。下面借助源码分析:

    /**
     * Atomically increments by one the current value.
     *
     * @return the previous value
     */
    public final int getAndIncrement() {
        for (;;) {
            int current = get();    //获取当前值
            int next = current + 1; //执行加1操作
            if (compareAndSet(current, next))
                return current;     //返回当前值
        }
    }

可以看出,通过compareAndSet方法,保证原子操作。

    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

调用Unsafe类的compareAndSwapInt方法。Unsafe类中方法为native方法,具体未看,原理就是利用CAS。

java有8个基本类型,而这里只有3个,那么其他5个如果也想原子操作呢?其实可以参考AtomicBoolean的实现,它先将boolean类型值转换成int。

数组

原子数组类型参见图中绿色框中的3个类。其底层实现逻辑和原子基本类型一致,这里我们看看如何使用数组类型。

static int[] value = new int[]{1,2};
    static AtomicIntegerArray ai = new AtomicIntegerArray(value);

    public static void main(String[] args){
        ai.getAndSet(0, 3);
        System.out.println(value[0]);
        System.out.println(ai.get(0));
    }

思考一下输出,再看结果:

1
3

是不是和你预想的不一样?传递的数组,为什么没有更改原始数组呢?AtomicIntegerArray会复制传递过来的数组,所以,AtomicIntegerArray修改内部数组元素时,不会影响传入的数组。

原子引用类型

3个原子引用类型,参加图中黄色框中的类。

  • AtomicReference:原子引用类型
  • AtomicStampedReference:原子带有版本号的引用类型
  • AtomicMarkableReference:原子带有标记位的引用类型

原子字段类

参见上图未框住的3个类。
需要注意的是,因为原子字段类为抽象类,每次使用时,通过静态方法newUpdater()创建一个更新器,并且设置需要更新的类和属性。同时,更新类的字段必须用volatile修饰。

参考:《Java并发编程的艺术》

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值