Thread.sleep()花费的时间比预期的长?

时间:2016-02-11 16:29:36

标签: java multithreading rmi sleep

我们有一个使用持久性框架的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失去与服务器的连接。 / p>

然而,我们遇到过这样的情况:线程运行得很好并且每15秒检查一次,然后由于未知原因,线程将出去吃午餐超过45秒。最终客户端将重新检入,但似乎有些东西在此期间阻止了线程的执行。我们在客户端使用Swing和JavaFX体验过这一点。客户端/服务器仅与Windows操作系统兼容。

是否有一种简单的方法可以找出导致这种情况发生的原因,或者采取更好的方法来确保检查确定以15秒的间隔定期发生,假设它们是客户端和服务器之间的连接?

3 个答案:

答案 0 :(得分:0)

  

getServer()的检入(用户id);

getServer或checkIn函数可能需要15秒以上才能返回,因此

  

线程将出去吃午饭超过45秒。

答案 1 :(得分:0)

当客户端计算机进入睡眠或休眠模式时,可能会发生这种情况。通常当它是一台笔记本电脑关闭时。

也可能有临时网络中断持续时间> 15秒,但允许连接在网络恢复时自动恢复。在这种情况下,客户端可能会陷入.checkIn(),而不是sleep()

答案 2 :(得分:0)

你绝对应该不这样做。在RMI中没有连接, ergo 您正在测试不存在的条件。您也在干扰RMI的连接池。完成您尝试的内容的正确方法是通过remote session patternUnreferenced界面。 RMI已经可以告诉您客户端何时失去连接,而没有所有这些开销。 “仍然连通”对RMI没有任何意义。