【发布时间】:2016-03-22 13:32:48
【问题描述】:
我试图创建一些场景来演示可见性问题,同时跨线程共享变量。而且我注意到,在我测试的几乎所有情况下,如果在 run() 中我在使用共享变量的同一代码块中添加了 System.out.println() 语句,则不会产生可见性问题。我举一个例子:
配置详细信息 - Oracle Java6 64 位、Eclipse Juno SR 2
-
1) 存在可见性问题:
public class NoVisibility_Demonstration extends Thread { boolean keepRunning = true; public static void main(String[] args) throws InterruptedException { NoVisibility_Demonstration t = new NoVisibility_Demonstration(); t.start(); Thread.sleep(1000); t.keepRunning = false; System.out.println("keepRunning is false"); } public void run() { int x = 1; while (keepRunning) { //System.out.println("If you uncomment this line, the code will work without the visibility issue"); x++; } System.out.println("x:"+x); }}
输出:线程无限运行
- 2) 没有可见性问题:
与上面相同的代码,在 run() 中使用未注释的 println() 语句
输出:
...
如果您取消注释此行,代码将在没有可见性问题的情况下运行
如果您取消注释此行,代码将在没有可见性问题的情况下运行
如果您取消注释此行,代码将在没有可见性问题的情况下运行
x:19391
keepRunning 为假
由于我在我尝试的所有示例中都注意到了类似的行为,我想知道在任何 I/O 操作之前 JVM 是否有任何数据完整性检查。
【问题讨论】:
-
在
while循环中使用System.out.println()将对每个循环迭代完成的速度产生相当大的影响。写入控制台是慢,简单地增加一个int变量是非常快的。只是需要牢记。 -
@JonK 我注意到在我编写的另一个程序中。是的,差异是巨大的。
标签: java multithreading