网站 如何 备案,河北品牌网站建设,网站建设为什么需要备案,黄金网站app免费视频大全目录
一、处理器如何实现原子操作#xff1f;
1.使用总线锁保证原子性
1.使用缓存锁保证原子性
二、Java如何实现原子操作#xff1f;
1#xff09;使用循环CAS实现原子操作
2#xff09;CAS实现原子操作的三大问题
3#xff09;使用锁机制实现原子操作 前言 原子
1.使用总线锁保证原子性
1.使用缓存锁保证原子性
二、Java如何实现原子操作
1使用循环CAS实现原子操作
2CAS实现原子操作的三大问题
3使用锁机制实现原子操作 前言 原子atomic本意是“不能被进一步分割的最小粒子”而原子操作atomic operation意 为“不可被中断的一个或一系列操作”。在多处理器上实现原子操作就变得有点复杂。让我们 一起来聊一聊在Intel处理器和Java里是如何实现原子操作的。
一、处理器如何实现原子操作 1.使用总线锁保证原子性 第一个机制是通过总线锁 保证 原子性 如果多个 处 理器同 时对 共享 变 量 进 行 读 改写操i 就是 经 典的 读 改写操作那么共享 变 量就会被多个 处 理器同 时进 行操作 这样读 改写操 作就不是原子的操作完之后共享变 量的 值 会和期望的不一致。 举 个例子如果 i1 我 们进 行 两次i 操作我 们 期望的 结 果是 3 但是有可能 结 果是 2 如 图 所示。 1.使用缓存锁保证原子性 第二个机制是通过缓 存锁定来保证原子性 在同一 时 刻我 们 只需保 证对 某个内存地址 的操作是原子性即可但 总线锁 定把 CPU 和内存之 间 的通信 锁 住了 这 使得 锁 定期 间 其他 处 理器不能操作其他内存地址的数据所以 总线锁 定的开 销 比 较 大目前 处 理器在某些 场 合下 使用 缓 存 锁 定代替 总线锁 定来 进 行 优 化。 但是有两种情况下处理器不会使用缓存锁定 第一种情况是当操作的数据不能被缓存在处理器内部或操作的数据跨多个缓存行 cache line时则处理器会调用总线锁定。 第二种情况是有些处理器不支持缓存锁定。对于Intel 486和Pentium处理器就算锁定的 内存区域在处理器的缓存行中也会调用总线锁定。 二、Java如何实现原子操作
1使用循环CAS实现原子操作
① 什么是CAS
典型的 比较并交换Compare-And-Swap, CAS操作通常用于实现无锁并发编程。CAS 是一种原子操作用于在多线程环境下确保数据的一致性。
public final boolean compareAndSet(int expect, int update) {return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
} 方法签名public final boolean compareAndSet(int expect, int update): expect期望的当前值。 update要更新的新值。 返回值如果操作成功返回 true否则返回 false。 方法实现:unsafe.compareAndSwapInt(this, valueOffset, expect, update): unsafe: 是一个 Unsafe 类的实例提供了低级别、不安全的底层由C实现的方法通常用于直接操作内存。 this: 当前对象的引用。 valueOffset: 当前对象中某个字段的内存偏移量用于定位该字段在内存中的位置。
CAS 工作原理
CAS 操作包含三个操作数内存位置由 this 和 valueOffset 确定、期望值expect。新值update。
CAS 操作的执行过程如下 检查内存位置的当前值是否等于期望值expect。 如果相等则将内存位置的值更新为新值update并返回 true。 如果不相等则不进行任何操作并返回 false。 ② 什么是自旋CAS当一个线程尝试用CAS操作更新某个共享变量时若操作失败线程不会进入阻塞而是循环进行CAS操作直到成功为止
自旋 CAS 的特点 无锁自旋 CAS 不需要使用锁如 synchronized 或 ReentrantLock避免了锁带来的开销如上下文切换、线程阻塞等。 乐观并发控制它前提假设竞争不会频繁发生因此线程会持续尝试更新而不是直接进入阻塞状态。 适用于低竞争场景 在低竞争情况下自旋 CAS 的性能优于锁。 但在高竞争场景下自旋 CAS 可能导致大量的 CPU 资源浪费因为线程会不断重试。 可能引发 ABA 问题 2CAS实现原子操作的三大问题
问题一ABA问题 CAS在操作值的时候会检查值有没有发生变化如果没有发生变化则更新但是如果一个值原来是A变成了B又变成了A那么使用CAS检查时会发现它的值没有发生变化但是实际上却变化了。危害如下 数据不一致如果程序逻辑依赖于变量的变化历史ABA 问题可能导致数据不一致。 逻辑错误ABA 问题可能导致程序逻辑错误。例如在无锁链表中节点的指针可能被错误地更新。 解决思路就是使用版本号JDK的Atomic包提供了AtomicStampedReference类来解决ABA问题。该类的compareAndSet方法的作用是首先检查当前引用是否等于预期引用并且检查当前标志是否等于预期标志如果全部相等才进行更新值。 问题二 长时间CAS不成功开销大
自旋CAS如果长时间不成功会给CPU带来非常大的执行开销 问题三只能保证一个共享变量的原子操作 对多个共享变量操作时循环CAS就无法保证操作的原子性这个时候就可以用锁 或者将多个变量合并JDK提供了AtomicReference类来保证引用对象之间的原子性就可以把多个变量放在一个对象里来进行CAS操作 3使用锁机制实现原子操作 锁机制保证了只有获得锁的线程才能够操作锁定的内存区域。JVM内部实现了很多种锁机制有偏向锁、轻量级锁和互斥锁。有意思的是除了偏向锁JVM实现锁的方式都用了循环CAS即当一个线程想进入同步块的时候使用循环CAS的方式来获取锁当它退出同步块的时候使用循环CAS释放锁。