浅析atomic原子性

什么是atomic

java.util.concurrent.atomic包中的很多类使用很高效的机器级指令(而不是锁)来保证操作的原子性。

有哪些常用的类

查看api可以知道atomic包下含有以下
浅析atomic原子性_第1张图片
比较常用的有AtomicBoolean、AtomicInteger、AtomicIntegerArray、AtomicLong等。

看看怎么使用

以AtomicLong举例,得到一个AtomicLong对象之后,可以使用incrementAndGet和decrementAndGet通过原子方式将一个整数自增或者自减。

public static AtomicLong nextNumber = new AtomicLong();
long id = nextNumber.incrementAndGet();
这里的incrementAndGet是原子方式,获得值、增加1然后设置成新的值的操作不会被中断,保证了线程安全。
还可以使用compareAndSet来实现更复杂的操作。

public static AtomicLong largest = new AtomicLong();
long observed = getObserved();
do{
	long oldValue = largest.get();
	long newValue = Math.max(oldValue, observed);
}while(!largest.compareAndSet(oldValue, newValue));
如果另一个线程也在更新largest,就可能阻止这个线程更新,compareAndSet就会返回false,不会设置新值。这时循环会尝试更新,读取更新后的值,知道修改成功,即compareAndSet返回true。在Java8中可以使用lambda表达式来更新变量,相对来说就更简介。
largest.updateAndGet(x -> Math.max(x, observed);
largest.accumulateAndGet(observed, Math::max);
以上两种方法均可。

Java8新增加

除了上面的updateAndGet和accumulateAndGet以外,还有getAndUpdate和getAndAccumulate实现返回原值。而当大量线程访问相同的原子值,性能会大幅下降,所以Java8提供了LongAdder和LongAccumulator来解决该问题。




你可能感兴趣的:(并发)