Java 从JDK 1.5开始提供了java.util.concurrent.atomic包(以下简称Atomic包),这个包中的原子操作类提供了一种用法简单、性能高效、线程安全地更新一个变量的方式。原子类通过 CAS (compare and swap) 、 volatile和native方法实现,比 synchronized 开销更小,执行效率更高,在多线程环境下,无锁的进行原子操作。
Atomic包分类
对其进行分类如下:
为了避免一个章节内容过多,导致大家提前下车,会通过几个章节进行 Atomic 包下面的知识讲解。
基本类型
基本类型有AtomicBoolean 、 AtomicInteger 、AtomicLong、这 3 个类提供的方法几乎一模一样,本章节以 AtomicLong为案例进行讲解,提前小剧透为了在后面和LongAdder 进行对比,LongAdder 和 AtomicLong 在面试中也被问到过呢。
AtomicLong 的常用方法如下方法名说明long getAndIncrement()以原子方式将当前值加1,注意,返回的是旧值。(i++)
long incrementAndGet()以原子方式将当前值加1,注意,返回的是新值。(++i)
long getAndDecrement()以原子方式将当前值减 1,注意,返回的是旧值 。(i--)
long decrementAndGet()以原子方式将当前值减 1,注意,返回的是旧值 。(--i)
long addAndGet(int delta)以原子方式将输入的数值与实例中的值(AtomicLong里的value)相加,并返回结果
long getAndSet(int newValue)以原子方式设置为newValue的值,并返回旧值
long get()_获取 AtomicLong 中的值(value)_
boolean compareAndSet(int expect,int update)如果输入的数值等于预期值,则以原子方式将该值设置为输入的值。
void lazySet(int newValue)最终会设置成newValue,使用lazySet设置值后,可能导致其他线程在之后的一小段时间内还是可以读到旧的值。
.................
JDK 1.8 新增
long getAndUpdate(LongUnaryOperator updateFunction)定函数的结果原子更新当前值,返回上一个值。
long updateAndGet(LongUnaryOperator updateFunction)使用给定函数的结果原子更新当前值,返回更新的值。 该功能应该是无副作用的,因为尝试的更新由于线程之间的争用而失败时可能会被重新应用。
................温馨提示:i++、++i、i--、--i只是为了帮助大家理解、理解、理解,重要的事情说三遍,并不是底层的实现就是它们哟。
小试牛刀
古人云“是骡子是马拉出来溜溜“,一段代码撸起来,走你。public class AtomicExample1 {
/**
* 初始化为 0
*/
private static AtomicLong