读书笔记之《Java并发编程的艺术-第二章》之原子操作

大哥打扰一下,读书笔记之《Java并发编程的艺术-第二章》之原子操作
最新回答
假丶惆怅

2026-10-24 15:04:28

原子操作是指在多线程环境下不可被中断的一个或一系列操作,确保操作的完整性和一致性。以下是关于原子操作的详细解析:

  • 处理器实现原子操作

  • 处理器会保证基本内存操作的原子性,如从系统内存中读取或写入一个字节。

  • 最新的处理器能自动保证单处理器进行16/32/64位的操作是原子的,并提供总线锁定和缓存锁定两个机制来保证复杂内存操作的原子性。

  • 总线锁定:当处理器发出LOCK#信号时,其他处理器的请求会被阻塞,该处理器可以独占共享内存。

  • 缓存锁定:原子操作可以在缓存内部完成,同时通过缓存一致性协议,当A处理器修改缓存中的i时,其他处理器不能同时缓存i,即会使得其他处理器中对于共享变量的缓存失效。

  • Java实现原子操作的方式

  • 使用锁:Java可以使用锁来实现一段代码的原子操作,但这样开销比较大,会引起频繁的上下文切换。

  • 使用CAS操作:CAS算法的过程是比较简单的,它会包含三个参数(V,E,N)。V表示要更新的变量,E表示预期值,N值。当且仅当V等于E值时,才会将V的值设为N,如果V值和E值不同,说明已经有其他线程做了更新,则当前线程什么都不做。当多个线程同时使用CAS对变量进行操作时,只有一个会胜出并成功更新,其余会失败。失败的线程不会被挂起。

  • Java中对于基本类型的包装类都有对应的原子操作实现,比如AtomicBoolean、AtomicInteger等。以AtomicInteger为例,其中的incrementAndGet的实现是直接调用了Unsafe类的方法。

  • 引用类型的原子操作:可以使用AtomicReference。

  • 数组类型的原子操作:JDK提供了AtomicIntegerArray等数组类型的原子类。

  • CAS操作的ABA问题

  • CAS操作虽好,但它会遇到ABA问题,即一个变量先是A,后来变成了B,在比较时又变回了A,但CAS操作无法感知到这种情况。

  • 如果说我们是否可以修改当前值,不仅取决于当前值,还取决于它的变化,那么原有的CAS操作就无能为力了,因为它感知不到。

  • JDK提供了AtomicStampedReference,它在对象内部维护了时间戳,当更新数据时,不仅要更新数据,还要更新时间戳。当AtomicStampedReference设置对象值时,对象值以及时间戳都必须满足期望值,写入才会成功。