Java 并行 volatile i++

标签 java multithreading increment runnable race-condition

我有一个全局变量

volatile i = 0;

和两个线程。每个都执行以下操作:

i++;
System.out.print(i);

我收到以下组合。 12、21 和 22。

我理解为什么我没有得到 11(volatile 不允许缓存 i)并且我也理解 12 和 22。

我不明白的是怎么可能得到21?

获得这种组合的唯一可能方法是,稍后打印的线程必须首先将 i 从 0 增加到 1,然后缓存 i==1。然后另一个线程将 i 从 1 递增到 2,然后打印 2。然后第一个线程打印缓存的 i==1。但我认为 volatile 不允许缓存。

编辑:运行代码 10,000 次后,我得到了 11 一次。将 volatile 添加到 i 根本不会改变可能的组合。

markspace 是正确的:volatile 禁止缓存 ii++ 不是原子的。这意味着 i 在递增过程中仍然会“缓存”在寄存器中。

r1 = i
//if i changes here r1 does not change
r1 = r1 + 1 
i = r1

这就是为什么11还是可以的原因。 21 是因为 PrintStreams 不同步造成的(参见 Karol Dowbecki 的回答)

最佳答案

您的代码不能保证哪个线程会调用 System.out首先。

由于 volatile 关键字,i 的增量和读取按顺序发生,但打印没有。

关于Java 并行 volatile i++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54791318/

相关文章:

c++ - 互斥保护 std::condition_variable

java - 变量在概率程序中不递增

java - 无法从 tomcat 中取消部署我的 webapp war 文件

java - 什么是 JBPM?为什么要使用它?

java - 是否可以在单个端口上运行两个 NIO 服务器套接字?

java - 在 Amazon SDK 上使用 NTLM 身份验证配置代理设置时出现问题

Java多线程困惑

.net - 是否应该始终在 AsyncCallback 中调用 EndInvoke 委托(delegate)?

java - 关于增量的几次迭代的解释?

loops - 循环增量值