首页 > 解决方案 > AtomicInteger 如何是线程安全的

问题描述

我正在阅读一些关于 Java 中原子变量的文档。正如到处都写的那样,AtomicInteger 应该是线程安全的。

根据我对原子整数的理解,它的工作原理是比较和交换算法。当两个线程尝试在完全相同的时间增加相同的原子变量时,我无法理解这将如何工作。

说我有定义AtomicInteger var = 1,这被两个线程Thread_1Thread_2. var当两个线程同时尝试增加 时会发生什么T1。我知道这将是罕见的情况,但如果它发生了怎么办。在比较和交换中,它在单个原子操作中读取和更新变量,并检查内存中的值。那么如果在 time T1-1, var 的值是 5 并且两者都Thread1Thread2开始递增呢?哪一个会失败?会是随机行为吗?或者我错过了一些非常基本的东西。

标签: javamultithreadingatomicinteger

解决方案


比较和交换在 CPU 级别是原子的。

您可以使用比较和交换显式实现增量操作:

int value;
do { 
  value = var.get();
} while (!var.compareAndSwap(value, value + 1));

CPU 保证它compareAndSwap是原子的(会有一个本机实现)。

如果两个线程同时命中这个compareAndSwap,只有其中一个会“获胜”,true作为compareAndSwap调用的结果接收,所以循环停止。

另一个线程将“丢失”并接收false结果,因此将再次循环:它读取一个新值,然后再次尝试 CAS。如果成功(因为没有其他线程同时尝试执行此操作,或者它“胜过”另一个线程),则循环停止;否则,它只是再次尝试。


推荐阅读