Java从JDK1.5开始提供了java.util.concurrent.atomic包,这个包中的原子操作类提供了一个种用法简单、性能高效、线程安全的更新变量的一个方式
原子更新基本类型
Atomic提供了3个类:
- AtomicBoolean:原子更新布尔类型
- AtomicInteger:原子更新整型
- AtomicLong:原子更新长整型
3个类提供的方法基本一模一样;
主要方法如下:
- int addAndGet(int delta): 以原子的方式输入的数值与实例中的值(AtomicInteger里的value)相加,并返回结果
- boolean compareAndSet(int expect, int update):如果输入的值于预期的值相等,则以原子方式将该值设置为输入的
- int getAndIncrement():以原子的方式将当前值+1,返回的是自增之前的值
- void lazySet(int newValue): 参考一个文章“http://ifeve.om/how-does-atomiclong-lazyset-work/”
- int getAndSet(int newValue):以原子方式设置newValue值,并返回旧值
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author iu
* 原子方式操作Integer类型
*/
public class AtomicIntegerTest {
static Integer integer = 10;
static AtomicInteger atomicInteger = new AtomicInteger(integer);
public static void main(String[] args) {
System.out.println(atomicInteger.getAndIncrement());
System.out.println(atomicInteger.get());
}
}
10
11
Process finished with exit code 0
原子更新数组
通过原子的方式更新数组里面的某人数据,Atomic提供了以下几个类
- AtomicIntegerArray
- AtomicLongArray
- AtomicReferenceArray
在AtomicIntegerArray中提供了2个方法:
- int addAndGet(int i, int delta):以原子的方式将输入值与数组中索引位置i的元素相加
- boolean compareAndSet(int i, int expect, int update):如果当前值等于预期值,则以原子方式将数组位置i的元素设置为update值。
import java.util.concurrent.atomic.AtomicIntegerArray;
/**
* @author iu
* 原子方式操作integer类型数组
*/
public class AtomicIntegerArrayTest {
static int[] value = new int[] {1,2,3};
static AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(value);
public static void main(String[] args) {
System.out.println(atomicIntegerArray.addAndGet(0,5));
System.out.println(value[0]);
System.out.println(atomicIntegerArray.compareAndSet(0,6,10));
System.out.println(atomicIntegerArray.get(0));
}
}
6
1
true
10
Process finished with exit code 0
原子更新引用类型
- AtomicReference:原子更新引用类型
- AtomicReferenceFieldUpdate:原子更新引用类型里的字段
- AtomicMarkableReference:原子更新带有标记位的引用类型
原子更新字段类
- AtomicIntegerFieldUpdate:原子更新整型的字段的更新器
- AtomicLongFieldUpdate:原子更新长整型字段的更新器
- AtomicStampedReference:原子更新带有版本号的引用类型。可以用来解决CAS进行原子更新时出现的ABA问题(将版本号和数值关联起来)