Java Atomic总结

本文详细介绍了Java中的原子类Atomic,包括CAS原理、原子更新普通类型、数组、引用及字段。Atomic类借助Unsafe通过CAS操作实现无锁的线程安全更新,避免了锁的开销。文中还探讨了ABA问题和JDK8引入的改进类型,如DoubleAdder和LongAdder。
摘要由CSDN通过智能技术生成

所谓 Atomic,翻译过来就是原子。原子被认为是操作中最小的单位,一段代码如果是原子的,则表示这段代码在执行过程中,要么执行成功,要么执行失败。原子操作一般都是底层通过 CPU 的指令来实现。而 atomic 包下的这些类,则可以让我们在多线程环境下,通过一种无锁的原子操作来实现线程安全。

atomic 包下的类基本上都是借助 Unsafe 类,通过 CAS 操作来封装实现的。Unsafe 这个类不属于 Java 标准,或者说这个类是 Java 预留的一个后门类,JDK 中,有关提升性能的 concurrent 或者 NIO 等操作,大部分都是借助于这个类来封装操作的。
Java 是种编译型语言,不像 C 语言能支持操作内存,正常情况下都是由 JVM 进行内存的创建回收等操作,但这个类提供了一些直接操作内存相关的底层操作,使得我们也可以手动操作内存,但从类的名字就可以看出,这个类不是安全的,官方也是不建议我们使用的。

CAS原理

CAS 包含 3 个参数 CAS(V,E,N). V 表示要更新的变量, E 表示预期值, N表示新值.

仅当V值等于E值时, 才会将V的值设为N, 如果V值和E值不同, 则说明已经有其他线程做了更新, 则当前线程什么都不做. 最后, CAS返回当前V的真实值. CAS操作是抱着乐观的态度进行的, 它总是认为自己可以成功完成操作.

当多个线程同时使用CAS操作一个变量时, 只有一个会胜出, 并成功更新, 其余均会失败.失败的线程不会被挂起,仅是被告知失败, 并且允许再次尝试, 当然也允许失败的线程放弃操作.基于这样的原理, CAS操作即时没有锁,也可以发现其他线程对当前线程的干扰, 并进行恰当的处理.

在 JDK8 的 atomic 包下,大概有 16 个类,按照原子的更新方式,大概可以分为 4 类:原子更新普通类型原子更新数组原子更新引用原子更新字段

原子更新普通类型

atomic 包下提供了三种基本类型的原子更新,分别是 AtomicBoolean,AtomicInteger,AtomicLong,这几个原子类对应于基础类型的布尔,整形,长整形,至于 Java 中其他的基本类型,如 float 等,如果需要,可以参考这几个类的源码自行实现。

AtomicBoolean

主要接口

 
public final boolean get();
public final boolean compareAndSet(boolean expect, boolean update);
public boolean weakCompareAndSet(boolean expect, boolean update);
public final void set(boolean newValue);
public final void lazySet(boolean newValue);
public final boolean getAndSet(boolean newValue);

这里面的操作都很正常,主要都是用到了 CAS。这个类中的方法不多,基本上上面都介绍了,而内部的计算则是先将布尔转换为数字0/1,然后再进行后续计算。

AtomicLong

主要接口

 
public final long get();
public final void set(long newValue);
public final void lazySet(long newValue);
public final long getAndSet(long newValue);
public final boolean compareAndSet(long expect, long update);
public final boolean weakCompareAndSet(long expect, long update);
public final long getAndIncrement();
public final long getAndDecrement();
public final long getAndAdd(long delta);
public final long incrementAndGet();
public final long decrementAndGet();
public final long addAndGet(long delta);
public final long getAndUpdate(LongUnaryOperator updateFunction);
public final long updateAndGet(LongUnaryOperator updateFunction);

这个和下面要讲的 AtomicInteger 类似,下面具体说下。

AtomicInteger

主要接口

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值