Java程序输出-并发
这可能是一个愚蠢的问题,但是,这个程序的输出(现在的方式)能为零吗 我问这个问题的原因是,尽管我使用的是AtomicInteger,但MyTest2中的if()语句可能会首先执行,然后x的值为零。对吗 或者说我的想法不正确 任何帮助都将不胜感激 这个程序的输出(按现在的方式)能为零吗 是的,那是可能的。代码不保证Java程序输出-并发,java,concurrency,Java,Concurrency,这可能是一个愚蠢的问题,但是,这个程序的输出(现在的方式)能为零吗 我问这个问题的原因是,尽管我使用的是AtomicInteger,但MyTest2中的if()语句可能会首先执行,然后x的值为零。对吗 或者说我的想法不正确 任何帮助都将不胜感激 这个程序的输出(按现在的方式)能为零吗 是的,那是可能的。代码不保证t1将在t2完成之前完成。如果这是你的意图,你可能会发现或有用。单击链接,它们的Javadoc包含代码示例 也就是说,我宁愿将AtomicInteger的引用作为两个可运行项的构造函数
t1
将在t2
完成之前完成。如果这是你的意图,你可能会发现或有用。单击链接,它们的Javadoc包含代码示例
也就是说,我宁愿将
AtomicInteger
的引用作为两个可运行项的构造函数参数传递,而不是以静态方式访问它。只需一个小改动,就可以保证输出将是1
:
public void run(){
int x = 1;
if(Test2.c.b.get() == 1)
x = Test2.c.a;
System.out.println("Value of x = "+x);
}
由于易失性读/写的顺序保证:
最初是x
1
- 可以分配给
的唯一其他值是x
Test2.c.a
仅当先前从Test2.c.a
读取了Test2.c.b
时,才能复制到1
x
仅在将1
写入1
Test2.c.a
- 由于
是易失性的,因此读取它的任何线程也会观察到以前写入Test2.c.b
的同一线程对所有变量(易失性或非易失性)的所有写入。这意味着Test2.c.b
还可以看到t2
写入1
Test2.c.a
- 如果测试失败(即读取
返回的不是Test2.c.b
),则x保留其初始值1
,因此输出仍然是1
1
我怀疑这就是这个程序的作者试图说明的,而
x
的默认值0
是一个输入错误。谢谢。。。我理解。。。我刚刚在某个地方看到了这段代码,注释是“output will is 1”——因此我将其发布在这里;t2.start();然后输出总是1,但如果将顺序颠倒为:t2.start();t1.start();那么输出总是0。这真的很奇怪,因为即使运行了100次,我也不能让它为相同的顺序产生不同的输出。也许你有一个单核CPU。在我的双核机器上,我看到0
大约每5次运行一次。无论如何,到目前为止发布的代码都不能保证线程以任何方式同步。线程在没有一些同步辅助的情况下过着各自的生活。对于另一个使用CyclicBarrier
的代码示例,您可能会发现有用的.Achilles-这是并发错误中最棘手的问题之一。通常情况下,您可以编写根据JLS不明确的代码,但这会在JVM和硬件的特定组合上产生预期的结果。您的JVM可以生成替代输出,但实际上从来没有。当代码在其他地方运行时,由于另一个环境被模糊性绊倒,它突然失败了。很好的解释,但在我看来,最初的作者只是犯了一个思维错误,更改默认返回值不是一个解决方案,而是一个解决办法。那么,使用线程的目的是什么呢?
public void run(){
int x = 1;
if(Test2.c.b.get() == 1)
x = Test2.c.a;
System.out.println("Value of x = "+x);
}