千锋教育-做有情怀、有良心、有品质的职业教育机构

手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

当前位置:首页  >  技术干货  > AtomicInteger 在高并发下性能不好,为什么?

AtomicInteger 在高并发下性能不好,为什么?

来源:千锋教育
发布人:xqq
时间: 2023-10-14 22:17:58 1697293078

一、竞争激烈导致自旋等待

在高并发情况下,多个线程同时竞争 AtomicInteger 的更新操作,会导致自旋等待。自旋等待是指线程在获取不到锁时,不会立即进入阻塞状态,而是一直忙等(自旋)直到获取到锁为止。自旋等待会消耗大量的 CPU 资源,降低性能。

二、缓存行失效引发伪共享

AtomicInteger 的内部实现依赖于 CPU 提供的 CAS(Compare and Swap)指令来实现原子性。但多个 AtomicInteger 变量可能会被存储在同一个缓存行中,当一个线程修改其中一个变量时,会导致整个缓存行失效,引发伪共享问题。其他线程访问不相关的变量时也会受到影响,增加了总线通信和缓存同步的开销,降低性能。

三、ABA 问题导致的无效更新

ABA 问题是指一个变量的值在经过多次修改后,又回到原始值,但中间经历了其他值。在高并发环境下,如果一个线程在检查值是否为期望值时发生了多次 ABA 更新,但此时有其他线程修改了该值并又恢复为原始值,那么这个检查就会出现误判,导致无效更新,降低了数据的正确性和性能。

四、无法保证多个操作的原子性

AtomicInteger 提供了一些原子性操作,如 getAndIncrement()、getAndDecrement()、getAndAdd() 等。但在多个操作组合的场景下,不能保证这些操作的原子性。比如在 getAndIncrement() 和 getAndDecrement() 组合的情况下,可能会出现并发问题,导致结果不符合预期。

五、线程频繁阻塞与唤醒导致的上下文切换开销

在高并发环境中,如果多个线程竞争一个 AtomicInteger 实例,可能会导致频繁的线程阻塞和唤醒,引发大量的上下文切换。上下文切换会导致 CPU 的资源浪费,降低系统的性能。

六、CAS 自旋次数限制影响性能

AtomicInteger 的 CAS 操作在失败时会进行自旋,但自旋次数有限。如果自旋次数不够多,就可能导致更新操作失败,增加了线程重新尝试的开销,降低了性能。

七、原子操作复杂性导致执行时间较长

AtomicInteger 提供的原子操作虽然是线程安全的,但其实现可能较为复杂,需要进行多次 CAS 尝试或者采用其他机制来保证原子性。这些额外的操作会增加原子操作的执行时间,从而降低了性能。

延伸阅读

AtomicInteger是什么

AtomicInteger是Java中提供的一个原子操作类,用于对整型数据进行原子性操作。它位于java.util.concurrent.atomic包下。原子操作指的是不可分割的、线程安全的操作。在并发环境下,多个线程同时对同一变量进行读写操作时,可能引发竞态条件和数据不一致的问题。而使用AtomicInteger可以保证对整型数据进行原子性操作,避免了这些问题。

AtomicInteger提供了一系列原子性操作方法,包括原子增减、原子赋值、原子比较和设置等,这些方法都能够保证在多线程环境下的原子性。它们底层使用了硬件支持或加锁机制,确保了操作的原子性和线程安全性。使用AtomicInteger不需要显式地加锁,因此在性能上比传统的加锁方式更高效。同时,AtomicInteger还提供了一些有用的方法,如getAndIncrement()、getAndSet()等,方便对变量进行自增、赋值等常见操作。

声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。
10年以上业内强师集结,手把手带你蜕变精英
请您保持通讯畅通,专属学习老师24小时内将与您1V1沟通
免费领取
今日已有369人领取成功
刘同学 138****2860 刚刚成功领取
王同学 131****2015 刚刚成功领取
张同学 133****4652 刚刚成功领取
李同学 135****8607 刚刚成功领取
杨同学 132****5667 刚刚成功领取
岳同学 134****6652 刚刚成功领取
梁同学 157****2950 刚刚成功领取
刘同学 189****1015 刚刚成功领取
张同学 155****4678 刚刚成功领取
邹同学 139****2907 刚刚成功领取
董同学 138****2867 刚刚成功领取
周同学 136****3602 刚刚成功领取
相关推荐HOT