编程语言
首页 > 编程语言> > Java parallel volatile i

Java parallel volatile i

作者:互联网

我有一个全局变量

volatile i = 0;

和两个线程.每个都做以下事情:

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

我收到以下组合. 12,21和22.

我理解为什么我没有得到11(挥发性不允许缓存我),我也理解12和22.

我不明白的是如何获得21?

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

编辑:运行代码10,000次后,我得到11次.向i添加volatile不会改变可能的组合.

markspace是对的:volatile禁止缓存i但我不是原子的.这意味着在增量期间我仍然会在寄存器中被“缓存”.

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

这就是11仍然可能的原因.引起21是因为PrintStreams不同步(参见Karol Dowbecki的回答)

解决方法:

不幸的是,这不是原子操作.尽管volatile不允许缓存,但允许JVM读取,递增,然后作为单独的操作写入.因此,您尝试实现的概念是不可行的.您需要对其互斥锁使用synchronized,或者使用类似AtomicInteger的东西来提供原子增量操作.

标签:java,multithreading,increment,race-condition,runnable
来源: https://codeday.me/bug/20190717/1485963.html