System.out.println行影响逻辑的执行
System.out.println Line Affecting Execution of the Logic
我已经运行陷入了一个难以置信的奇怪现象。我目前正在 Java 中编写一个即时消息程序,我有一个变量来表示新用户是否已连接(这是在单独的 class 中)。这是有问题的代码,其中对象 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 是一个并发的 运行ning 线程。除了我当前的代码,我似乎无法复制这个结果。
[EDIT] 用 Thread.sleep(1)
替换 System.out.println
似乎也有效,所以这让我认为这是一个并发问题。
一点也不奇怪,你肯定在多线程系统中并且你的应用程序正在获取过时的 boolean
值,你需要在读取变量 listenerThreadConnected 时确保内存可见性
如何:?
将此 boolean listenerThreadConnected
声明为易变的,错误必须消失!
请注意,System.out.println
通常实现为 synchronized
(即使没有记录),以便您不会得到两个线程交错的输出。
执行该语句具有使变量更新对执行同步方法的线程可见的效果(这是一种 "happens before" 关系)。
通过删除 System.out.println
调用,您将删除此行为,因此您可能会看到过时的变量。
正如@Xoce웃Пepeúpa 所说,创建变量 volatile
,或者做其他事情来确保内存可见性(例如将其更改为 AtomicBoolean
)。
我已经运行陷入了一个难以置信的奇怪现象。我目前正在 Java 中编写一个即时消息程序,我有一个变量来表示新用户是否已连接(这是在单独的 class 中)。这是有问题的代码,其中对象 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 是一个并发的 运行ning 线程。除了我当前的代码,我似乎无法复制这个结果。
[EDIT] 用 Thread.sleep(1)
替换 System.out.println
似乎也有效,所以这让我认为这是一个并发问题。
一点也不奇怪,你肯定在多线程系统中并且你的应用程序正在获取过时的 boolean
值,你需要在读取变量 listenerThreadConnected 时确保内存可见性
如何:?
将此 boolean listenerThreadConnected
声明为易变的,错误必须消失!
请注意,System.out.println
通常实现为 synchronized
(即使没有记录),以便您不会得到两个线程交错的输出。
执行该语句具有使变量更新对执行同步方法的线程可见的效果(这是一种 "happens before" 关系)。
通过删除 System.out.println
调用,您将删除此行为,因此您可能会看到过时的变量。
正如@Xoce웃Пepeúpa 所说,创建变量 volatile
,或者做其他事情来确保内存可见性(例如将其更改为 AtomicBoolean
)。