2016-04-04 28 views
0

我遇到了一个令人难以置信的奇怪现象。我目前正在使用Java编写即时通讯程序,并且我有一个变量来表示新用户是否已连接(这是在单独的类中)。这是有问题的地方对象ListenerThread extends Thread代码:System.out.println影响执行逻辑的线路

boolean listenerThreadConnected = ServerDriver.getListenerThread().connected; 
System.out.println("Whatever in here"); 
if(listenerThreadConnected){ 
    ... 
    System.out.println("In the if statement"); 
    ... 
} 

因此,此代码的工作。当listenerThreadConnected = true执行if语句时,它输出In the if statement并执行if语句中的所有其他内容。然而,除了注释掉System.out.println("Whatever in here")if声明没有触发,并且没有输出In the if statement的符号之外,我没有更改其他代码。我的代码看起来像这样:

boolean listenerThreadConnected = ServerDriver.getListenerThread().connected; 
//System.out.println("Whatever in here"); 
if(listenerThreadConnected){ 
    ... 
    System.out.println("In the if statement"); 
    ... 
} 

我很困惑。这个System.out.println怎么会影响实际的逻辑?我知道这个问题非常开放,但你有没有过类似的经历?对于某些上下文,这全部在while循环中,并且ListenerThread是并发运行的线程。我似乎无法复制这个结果,除了在我目前的代码。

[编辑]更换System.out.printlnThread.sleep(1)也似乎工作,所以这使我觉得这是一种并发问题。

回答

4

并非如此交流中心所有,你肯定在多线程系统和您的应用程序越来越过时的boolean值,你是在读变量listenerThreadConnected

如何时需要确保存储可见性:?

声明此boolean listenerThreadConnected为易失性,错误必须消失!

+0

非常感谢。对于多线程和并发来说很新颖。 – dsiegler19

2

请注意,System.out.println通常实现为​​(即使没有记录),以便您不会得到两个线程交错的输出。

执行该语句的效果是对执行同步方法的线程可见的变量进行更新(这是“发生之前”关系)。

通过删除System.out.println调用,您删除此行为,因此您可能会看到过时的变量。

作为@ Xoce웃Pepeúpa说,使变量volatile或做其他事情以确保内存可见性(例如将其更改为AtomicBoolean)。