Java AtomicInteger 使用指南
2019-12-03 本文已影响0人
程序员网址导航
AtomicInteger类通过提供对值执行原子操作的方法来保护基础的int值。 它不能代替Integer类。
从Java 1.5开始,AtomicInteger类是java.util.concurrent.atomic包的一部分。
1.AtomicInteger的创建、塞值、取值
通过调用构造函数,可以直接创建AtomicInteger。 AtomicInteger提供了两种方法来获取和设置其实例的值。
//Initial value is 0
AtomicInteger atomicInteger = new AtomicInteger();
//Initial value is 100
AtomicInteger atomicInteger = new AtomicInteger(100);
int currentValue = atomicInteger.get(); //100
atomicInteger.set(1234); //Now value is 1234
2.什么时候我们需要使用AtomicInteger
在实际开发中,在两种情况下我们将需要AtomicInteger:
1.作为多个线程同时使用的原子计数器。
2.在比较和交换操作中实现非阻塞算法。
2.1AtomicInteger作为原子计数器
要将其用作计数器,AtomicInteger类提供了一些方法来原子地执行加减运算。
- addAndGet():以原子方式将给定值添加到当前值,并在添加后返回新值。
- getAndAdd():以原子方式将给定值添加到当前值并返回旧值。
- crementAndGet():以原子方式将当前值增加1,并在增加之后返回新值。 它等效于++ i操作。
- getAndIncrement():以原子方式递增当前值并返回旧值。 它等效于i ++操作。
- decrementAndGet():以原子方式将当前值减1,并在减后返回新值。 它等效于i-操作。
- getAndDecrement():以原子方式减少当前值并返回旧值。 它等效于– -i操作。
public class Main
{
public static void main(String[] args)
{
AtomicInteger atomicInteger = new AtomicInteger(100);
System.out.println(atomicInteger.addAndGet(2)); //102
System.out.println(atomicInteger); //102
System.out.println(atomicInteger.getAndAdd(2)); //102
System.out.println(atomicInteger); //104
System.out.println(atomicInteger.incrementAndGet()); //105
System.out.println(atomicInteger); //105
System.out.println(atomicInteger.getAndIncrement()); //105
System.out.println(atomicInteger); //106
System.out.println(atomicInteger.decrementAndGet()); //105
System.out.println(atomicInteger); //105
System.out.println(atomicInteger.getAndDecrement()); //105
System.out.println(atomicInteger); //104
}
}
2.2 CAS(Compare and swap)操作
比较和交换操作将存储位置的内容与给定值进行比较,并且只有它们相同时,才将该存储位置的内容修改为给定的新值。 这是作为单个原子操作完成的。
原子性保证了根据最新信息计算新值; 如果与此同时值已由另一个线程更新,则写入将失败。
为了支持比较和交换操作,此类提供了一种方法,该方法可以在当前值==预期值的情况下,将值自动设置为给定的更新值。
boolean compareAndSet(int expect, int update)
import java.util.concurrent.atomic.AtomicInteger;
public class Main
{
public static void main(String[] args)
{
AtomicInteger atomicInteger = new AtomicInteger(100);
boolean isSuccess = atomicInteger.compareAndSet(100,110); //current value 100
System.out.println(isSuccess); //true
isSuccess = atomicInteger.compareAndSet(100,120); //current value 110
System.out.println(isSuccess); //false
}
}
Console, Program output:
true
false
结论
如上所述,AtomicInteger的主要用途是当我们处于多线程上下文中时,我们需要对int值执行原子操作,而无需使用synced关键字。
与使用同步执行AtomicInteger相比,使用AtomicInteger具有同样的速度和可读性。同样的在Java JCU下的atomic包下提供了AtomicLong、AtomicBoolean ……,可以在必要时候为我们提供安全的保障,且不必做一些复杂的操作。