我有一个全局变量
volatile i = 0;
和两个线程。每个执行以下操作:
i++;
System.out.print(i);
我收到以下组合。 12、21 和 22。
I understand why I don't get 11 (volatile disallows the caching of i) and I also understand 12 and 22.
我不明白的是怎么可能得到21?
获得此组合的唯一可能方法是稍后打印的线程必须是第一个递增的线程i
从0到1然后缓存i==1
。然后另一个线程递增i
从1到2,然后打印2。然后第一个线程打印缓存的i==1
。但我以为volatile
禁止缓存。
编辑:运行代码 10,000 次后,我得到了 11 次。添加volatile
to i
根本不会改变可能的组合。
标记空间是正确的:易失性禁止缓存i
but i++
不是原子的。这意味着i
在递增过程中仍然会被“缓存”在寄存器中。
r1 = i
//if i changes here r1 does not change
r1 = r1 + 1
i = r1
这就是11仍然可能的原因。 21 是因为 PrintStreams 不同步造成的(参见 Karol Dowbecki 的回答)
您的代码不保证哪个线程将调用System.out https://docs.oracle.com/javase/10/docs/api/java/lang/System.html#out first.
增量和读取i
由于按顺序发生volatile
关键字但 prints 没有。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)