This question already has an answer here:
Loop doesn't see value changed by other thread without a print statement
                                
                                    (1个答案)
                                
                        
                4年前关闭。
            
        

我正在使用KryoNet Java库以及光滑的基于服务器/客户端的游戏。当服务器类收到来自客户端的连接时,它将向客户端发送必要的启动信息,包括它的播放器编号。收到此消息的客户端开始滑动并开始正常运行。此代码是:

    boolean started = false;
    while(!started){
        System.out.println(cs.playerNum);
        if(cs.playerNum != -1){
            cs.startSlick();
            started = true;
        }
    }


当从服务器接收到值时,playerNum由另一个线程设置。有一阵子我无法使它工作(从未调用过cs.startSlick()),最终我感到沮丧,每次循环运行时就开始记录playerNum。通过添加System.out.println(cs.playerNum),代码开始工作,循环将正确评估并开始滑动。

System.out.println怎么可能这样做?我尝试用其他函数替换它,甚至尝试将cs.playerNum作为参数的其他函数替换它,但是只有当我专门打印cs.playerNum时,我才能使循环起作用。
如果需要包含更多源,则问题可能直接在这里,因为我尝试用其他功能替换System.out.println失败。

最佳答案

当您说“ playerNum由另一个线程设置”时,您会回答自己的问题。您拥有的是经典的比赛条件。如果您的代码能够足够快速地执行,那么该playerNum尚未被设置。但是,如果某些东西延迟或“中断”了您的代码,则另一个线程将有时间设置playerNum值,并且您的代码将按预期工作。

执行IO的系统调用在等待该IO操作发生时强行挂起了线程。当您调用System.out.println时,会发生这种情况,这会使您看似紧凑的代码暂时暂停到另一个线程,然后允许您检索所需的值。

这是一个非常基本的线程问题,您将在编写线程代码时遇到更复杂的线程问题。因此,我绝对建议您花一些时间来阅读一般的线程,并了解同步函数以及wait()和notify()的工作方式,如注释中所建议。

关于java - Java System.out.println()影响程序流程,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32870405/

10-12 23:53