System.out.println影响逻辑执行的行

时间:2016-04-04 14:49:52

标签: java multithreading if-statement boolean-logic system.out

我遇到了一个令人难以置信的奇怪现象。我目前正在使用Java编写一个即时消息程序,我有一个变量来表示新用户是否已连接(这是在一个单独的类中)。以下是对象ListenerThread extends Thread

中的代码
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是一个并发运行的Thread。除了我当前的代码之外,我似乎无法复制此结果。

[编辑] System.out.println替换Thread.sleep(1)似乎也有效,所以这让我觉得这是一个并发问题。

2 个答案:

答案 0 :(得分:4)

根本不是那么多,您肯定在多线程系统中并且您的应用程序获得了过时的boolean值,您需要在读取变量 listenerThreadConnected 时确保内存可见性

如何:吗

将此boolean listenerThreadConnected声明为volatile,错误必须消失!

答案 1 :(得分:2)

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

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

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

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