天天看点

Java 中 13个 原子操作类

前言

java 从jdk 1.5 开始提供了 java.util.concurrent.atomic包,这个包中原子操作类
提供了一种用法简单,性能高效,线程安全地更新一个变量的方式。      

因为变量有很多种,所以在automic包中提供了13类,属于4种类型的原子更新方式“

  1. 原子更新基本类型
  2. 原子更新数组
  3. 原子更新引用
  4. 原子更新属性(字段)

1.原子更新基本类型类

AtomicBoolean :原子更新布尔类型
 AtomicInteger:原子更新整形
 AtomicLong:原子更新长整型      

以上三个类方法几乎一摸一样,所以学习一个就能知道其它的怎么调用了,这里以 AtomicInteger 进行解释

public final int addAndGet(int delta). 以原子的方式将输入的数值与实例中值(AtomicInteger 中的Value)相加并返回结果。

public final boolean compareAndSet(int expect, int update) ,如果输入的数值等于预期值,则以原子的方式将该值设置为输入值

public final int getAndIncrement() 以原子的方式将当前值加 1.注意返回的是自增前的值

public final void lazySet(int newValue) 。最终会设置成newValue,使用lazySet 设置值后,可能会导致其他线程在之后一小段时间内还是可以读到旧

的值。

public final int getAndSet(int newValue) :以原子的方式设置为newValue的值,并返回旧值

代码清单

import java.util.concurrent.atomic.AtomicInteger;

public class AtomicIntegerTest {

    static AtomicInteger atomicInteger = new AtomicInteger(1);

    public static void main(String[] args) {
        System.out.println(atomicInteger.getAndIncrement());
        System.out.println(atomicInteger.get());
    }
}      
输出结果如下:

 1
 2      

Process finished with exit code 0

那么getAndInsrement 是如何实现原子操作的呢?

在jdk1.7中,AtomicInteger的getAndIncrement是这样的:

public final int getAndIncrement() {
    for (;;) {
        int current = get();
        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);
}      

而在jdk1.8中,是这样的:

public final int getAndIncrement() {
    return unsafe.getAndAddInt(this, valueOffset, 1);
}      

本文使用jdk 1.7 进行分析

unsafe源码


public final native boolean compareAndSwapObject(Object o, long offset, Object expected, Object x);

public final native boolean compareAndSwapInt(Object o, long offset, Object expected, Object x);

public final native boolean compareAndSwapLong(Object o, long offset, Object expected, Object x);