【发布时间】:2015-09-30 15:45:29
【问题描述】:
我正在使用 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 没有成功。
【问题讨论】:
-
有没有线程掉线? System.out.println 会导致当前线程暂停,允许其他线程做那里的事情。
-
不知道您的问题的答案,但这通常是非常糟糕的代码!如果一个线程必须等待另一个线程,请使用 wait() 和 notify()!忙碌的等待从来都不是一个好的选择,而且会导致像你这样的奇怪行为!
-
公平地说,我以前没有使用过多线程应用程序,所以我完全有可能做错了什么。我会考虑使用您的建议,但我仍然对正在发生的事情感到好奇。
-
@mlk 可能就是这样。如果另一个线程被启动并允许自己运行,那么在这个线程运行时它实际上不会做任何事情吗?另外,我尝试过 sleep() ing这个线程,但这并不能解决问题:那会做同样的事情吗?抱歉,我有点困惑,以前没有太多使用过线程。
-
发生了什么:另一个线程修改了
started变量,但是这个修改对于这个线程是不可见的。 (原因隐藏在缓存和 Java 内存模型中)。 可以通过将started变量声明为volatile(以确保每个线程都能看到更改)来解决,但是你正在做的是被称为“忙着等待”,这是一种非常不好的做法,除非您的目标是使用 CPU 来保持咖啡热气腾腾。你应该看看java.util.concurrent,也许用CountDownLatch左右来解决它...
标签: java multithreading slick system.out kryonet