Java 为什么这句话被认为是原子的?

Java 为什么这句话被认为是原子的?,java,concurrency,atomic,Java,Concurrency,Atomic,我有一个需要澄清的并发程序。第一个程序被认为是原子的,而第二个则不是 注意:此处的/并不表示注释-它们表示这是另一个进程与另一个进程同时执行 以下是第一点: int x = 0, y = 0; co x = y + 1; // y = y + 1; oc 上面的程序可以看作是原子的,但我不明白为什么会这样。但下一个节目不是 int x = 0, y = 0; co x = y + 1; // y = x + 1; oc 我知道原子操作是一种编程指令,它不可

我有一个需要澄清的并发程序。第一个程序被认为是原子的,而第二个则不是

注意:此处的
/
并不表示注释-它们表示这是另一个进程与另一个进程同时执行

以下是第一点:

int x = 0, y = 0;

co
   x = y + 1;      // y = y + 1;
oc
上面的程序可以看作是原子的,但我不明白为什么会这样。但下一个节目不是

int x = 0, y = 0;

co
   x = y + 1;      // y = x + 1;
oc

我知道原子操作是一种编程指令,它不可分割地改变计算机系统的状态,也知道从寄存器加载和存储值是一种典型的原子操作。那么上面是怎么回事呢?

请注意以下事实:

例1。Var
x
不共享,只有
y
共享。左线程严格来说是
y
的读卡器,右线程是
y
的写卡器。由于单个读写操作是原子操作,因此不存在竞争条件

例2。两个变量都是共享的;单凭这一事实就可以使操作非原子化,但由于读写的相互依赖性,这一点更加复杂。左线程:读取
y
之后是写入
x
,右线程:读取
x
之后是写入
y
。这些操作可以以任何顺序交错;甚至与程序顺序不兼容的顺序也是可能的


在第一个示例中,任何执行都将以可解释为
x=y+1的结果结束
y=y+1之前执行或相反。第二种解释的结果可能与上述任何一种解释都不符——这就是为什么ops不是原子的。

观察以下事实:

例1。Var
x
不共享,只有
y
共享。左线程严格来说是
y
的读卡器,右线程是
y
的写卡器。由于单个读写操作是原子操作,因此不存在竞争条件

例2。两个变量都是共享的;单凭这一事实就可以使操作非原子化,但由于读写的相互依赖性,这一点更加复杂。左线程:读取
y
之后是写入
x
,右线程:读取
x
之后是写入
y
。这些操作可以以任何顺序交错;甚至与程序顺序不兼容的顺序也是可能的


在第一个示例中,任何执行都将以可解释为
x=y+1的结果结束
y=y+1之前执行或相反。第二种情况可能会导致与上述任何一种解释都不兼容的结果——这就是ops不是原子的原因。

在第一种情况下,您总是会在增量之前或之后遇到
y
。由于操作是异步的,您无法分辨哪个操作是异步的,但这没有任何区别——唯一可以观察到的效果是,在一种情况下,
x
大于1,而在另一种情况下,这可能是基于两条语句的顺序发生的

在第二种情况下,您可以得到这样一种情况:x和y的结果值与语句的顺序不一致,因为x和y都是在修改任何一个之前获取的


第一种情况实际上不是Java对“原子”的定义(与编译器可能生成的任何“原子”指令无关),而是简单的编程。

在第一种情况下,您总是会在增量之前或之后遇到
y
。由于操作是异步的,您无法分辨哪个操作是异步的,但这没有任何区别——唯一可以观察到的效果是,在一种情况下,
x
大于1,而在另一种情况下,这可能是基于两条语句的顺序发生的

在第二种情况下,您可以得到这样一种情况:x和y的结果值与语句的顺序不一致,因为x和y都是在修改任何一个之前获取的


第一种情况实际上不是Java对“原子”的定义(与编译器可能生成的任何“原子”指令无关),而是简单的编程。

就线程而言,基本上是原子的,这意味着在另一个线程可以访问一个语句块之前,需要完全访问并执行该语句块。是这样的

x=x+1

现在,当一个线程访问变量x来读写它的值时,如果其他线程也尝试读写它,那么由于不吉利的计时(称为竞争条件)将导致问题,比如线程a读取变量x的值,该值可能为0,而此时线程B将该值作为1读写到x,现在,当线程A将值写入x时,它也将是1,因为线程A知道x是0,但实际上它是1

int x = 0, y = 0;

co
   x = y + 1;      // y = y + 1;
oc
与x一样是原子的,y值一次必须由同一个线程读取和写入,如果多个线程访问它,那么它将给出不一致的结果

int x = 0, y = 0;

co
   x = y + 1;      // y = x + 1;
oc

另一方面,这不是原子性的,因为x=y+1不会影响y=x+1,因为x和y上的提取在这里完成。

就线程而言,大部分原子性意味着在另一个线程可以访问一个语句块之前,需要访问并完全执行该语句块。是这样的

x=x+1

现在,当一个线程访问变量x来读写它的值时,如果其他线程也尝试读写它,那么由于不吉利的计时(称为竞争条件)将导致问题,比如线程a读取变量x的值,该值可能为0,而此时线程B将该值作为1读写到x,现在,当线程A将值写入x时,它也将是1,因为线程A知道x是0,但实际上它是1

int x = 0, y = 0;

co
   x = y + 1;      // y = y + 1;
oc
与x一样是原子的,y值一次必须由同一个线程读取和写入,如果多个线程访问它,那么它将给出不一致的结果

int x = 0, y = 0;

co
   x = y + 1;      // y = x + 1;
oc
O