Java System.out.println() 影响程序流程

标签 java multithreading slick system.out kryonet

我正在使用 KryoNet java 库以及 slick 开发基于服务器/客户端的游戏。当服务器类收到来自客户端的连接时,它会向客户端发送必要的启动信息,包括玩家编号。收到此消息后,客户端就会开始流畅并开始正常运行。其代码是:

    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),代码开始工作,循环将正确评估并启动 slick。

System.out.println 怎么可能做到这一点?我尝试用其他函数替换它,甚至其他以 cs.playerNum 作为参数的函数,但只有当我专门打印 cs.playerNum 时,我才能让循环工作。 如果我需要包含更多源代码,我可以,但问题似乎直接在这里,因为我尝试用其他函数替换 System.out.println 但没有成功。

最佳答案

当你说“playerNum是由另一个线程设置的”时,你有点回答了你自己的问题。你所拥有的是经典的竞赛条件。如果您的代码能够足够快地执行,那么在需要时,playerNum 将不会被设置。但是,如果某些事情延迟或“中断”您的代码,那么另一个线程将有时间设置playerNum 值,并且您的代码将按您的预期工作。

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

这是一个非常基本的线程问题,编写线程代码时您将遇到更复杂的线程问题。因此,我绝对建议您花一些时间阅读一般的线程技术,并了解同步函数以及 wait() 和 notification() 的工作原理,正如评论中所建议的那样。

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

相关文章:

java - 上传youtube视频服务器端

java - 如果 MaximumPoolSize 小于 corePoolSize 该怎么办? Java 6 中可能存在错误吗?

Scala Slick : MappedColumnType cannot find implicit value for BaseColumlnType[String]

java - Spring Data JPA - 为三个表创建 @Composite 键

java - 检测到符号后删除单词

android - 异步任务 OnProgressUpdate CalledFromWrongThreadException : Only the original thread that created a view hierarchy can touch its views

java - 线程类并将信息传递到主 Activity 类到 TextView 中

scala - 使用 Slick 1.0.0 计算行数

scala - 如何在 slick 中进行相关子查询?

java - 如何使用 Maven 创建一个 jar,其中包含每个依赖项的单独文件夹中的依赖项