【发布时间】:2016-05-22 13:15:34
【问题描述】:
我们有一个使用持久性框架的 Java 客户端/服务器 RMI 应用程序。在启动客户端会话时,我们启动以下线程:
Thread checkInThread = new Thread() {
public void run() {
while(true) {
try {
getServer().checkIn(userId);
}
catch(Exception ex) {
JOptionPane.showMessageDialog(parentFrame, "The connection to the server was lost.");
ex.printStackTrace();
}
try {
Thread.sleep(15000);
}
catch(InterruptedException e) {
}
}
}
};
这用于跟踪客户端会话是否失去与服务器的连接。如果客户端在 45 秒内没有签入,那么我们需要从该客户端的会话中清理许多事情。在他们超过 45 秒阈值后下一次签入时,我们从系统引导他们,然后允许他们重新登录。理论上,唯一应该发生的情况是客户端 PC 失去与服务器的连接。
但是,我们遇到过线程运行良好并且每 15 秒检查一次的情况,然后由于未知原因,线程将只出去吃午饭超过 45 秒。最终客户端将重新签入,但在此期间似乎有什么东西阻止了线程的执行。我们在客户端使用 Swing 和 JavaFX 都体验过这一点。客户端/服务器仅与 Windows 操作系统兼容。
是否有一种简单的方法可以找出导致这种情况发生的原因,或者是否有更好的方法来确保以 15 秒的间隔定期进行签入(假设它们是客户端和服务器之间的连接)?
【问题讨论】:
-
可能是睡眠前的部分阻塞,例如对话框已显示并等待用户交互?
-
我想知道日志记录是否会有所帮助。
-
顺便说一句,我希望空的 catch 块只是为了简单起见,而不是在现实中为空。
-
正如@HovercraftFullOfEels 所说,记录。具体来说,记录线程调用
sleep的时间和sleep返回的时间。这将确定延迟是在sleep,还是更有可能在其他地方。 -
我不同意这个副本。另一个问题的答案说,在非实时 JVM 和操作系统上,睡眠时间可能会超过给定的毫秒数。但是,迟到了 45 秒或更长时间?我认为这里正在发生其他事情。不能说没有更多信息——这个例子没有显示时间是如何测量的——但是 Huy Nguyen Ngoc 的回答似乎是合理的: OP 可能错误地将在
getServer().checkIn(userId);中花费的时间归因于 sleep()打电话。
标签: java multithreading rmi sleep