Java中什么是原子性

Tar*_*run 0 java multithreading atomic

我在实践中研究JAVA并发,发现原子操作的定义如下:

如果从执行 A 的线程的角度来看,操作 A、B 彼此是原子的,当另一个线程执行 B 时,B 要么全部执行完毕,要么全部执行完毕。原子操作是指对同一数据进行操作的所有操作(包括其本身)都是原子的

假设我有两个线程 A 和 B 都访问 AtomicLong 变量计数。
假设线程 A 读取 count 而线程 B 正忙于执行 count.incrementAndGe() 操作。
在这种情况下,根据上面的定义(要么所有 B 都已执行,要么没有执行):

A) ThreadA 查看之前的 count 值(因为 count 尚未更新)

或者

B) ThreadA 将等待,直到 ThreadB 完成操作并查看最新值。

根据我的理解,它应该是 B,因为否则我们仍然可能出现竞争条件。

Sol*_*low 5

您所描述的情况称为“数据竞争”。要么线程 A 将赢得比赛(它看到初始值),要么线程 B 将赢得比赛(线程 A 看到最终值)。除非您提供了一些显式方法来强制线程以特定顺序访问变量,那么就无法知道谁会赢得比赛。


“原子性”意味着线程 B 要么会看到原子操作之前的数据,要么会在操作完成后看到数据。线程 B 永远看不到它处于半完成状态。

用于更新单个 64 位long值。几乎唯一可能“半途而废”的方法是 64 位值在 32 位硬件上被破坏。如果组成 64 位值的两个 32 位字之一已更新,而另一个未更新,则该数据将被“撕裂”。

  • @Tarun,在两个线程都执行原子“getAndIncrement()”的情况下,原子性是双向的。如果线程 A 赢得了比赛,那么线程 B 将不会访问该变量,直到线程 A 完成整个操作(即,直到线程 A 发布了递增的值)。如果线程 B 赢得了比赛,那么线程 A 将不会访问该变量变量直到 B 完成。获胜者返回的值为原始值,失败者返回的值为原始值+1,最终计数为原始值+2。总是。 (4认同)