Thread.sleep()永远不会返回

20

我在使用Java的Thread.sleep()时遇到了奇怪的错误。在某些机器上,当我调用sleep时,它永远不会返回。我无法弄清楚是什么原因导致了这种行为。起初,我以为错误可能出现在我的代码的其他地方,因此我进行了最简单的sleep测试:

public class SleepTest {
    public static void main (String [] args) {
        System.out.println ("Before sleep...");
        try {
            Thread.sleep (100);
        } catch (InterruptedException e) {
        }
        System.out.println ("After sleep...");
    }
}

在大多数机器上它可以工作,但在我远程登录的一些机器上,它在打印语句之间无限期地暂停。我已经等了半个小时,行为没有任何改变。显示此错误的机器是Linux机器。以下是有关这些机器的一些信息:

$ uname -a
Linux zone29ea 2.6.32-220.17.1.el6.x86_64 #1 SMP Tue May 15 17:16:46 CDT 2012 x86_64 x86_64 x86_64 GNU/Linux
$ java -version
java version "1.6.0_22"
OpenJDK Runtime Environment (IcedTea6 1.10.6) (rhel-1.43.1.10.6.el6_2-x86_64)
OpenJDK 64-Bit Server VM (build 20.0-b11, mixed mode)

这种行为的原因可能是什么?

更新

仍然无法结束的修订版本:

public class SleepTest {
    public static void main (String [] args) {
        new Thread () {
            public void run () {
                System.out.println ("Before sleep...");
                try {
                    Thread.sleep (100);
                } catch (InterruptedException e) {
                    e.printStackTrace ();
                }
                System.out.println ("After sleep...");
            }
        }.start();
    }
}

2
你检查一下 catch 里面是否有错误被触发了吗?或者打印一下堆栈信息? - Adel Boutros
你能否尝试在单独的线程中运行以确保仍然发生这种情况?你现在正在让主线程休眠,这可能会导致问题。 - John Kane
1
你确定问题不在于第二个println的恢复(由于您是远程执行)吗?可能是缺少flush操作?即使在linux上,Thread.sleep(100); 也能够正常工作。 - Denys Séguret
你有可能在像jvisualvm这样的分析器中运行代码并获取一些调试信息吗? - posdef
非常有趣的问题。如果添加了 finally 子句会发生什么? - Radu Murzea
显示剩余2条评论
3个回答

13
如果您的服务器正在运行Linux操作系统,您可能会遇到上周末出现的闰秒Bug。该Bug影响了Linux内核(线程管理),因此使用线程的应用程序(如JVM、mysql等)可能会消耗大量CPU资源。

不,闰秒是在六月的最后一天的最后一个小时的最后一分钟添加的。但您的服务器的NTP进程可能存在问题。重新启动可能会解决问题。 - Jean-Philippe Briend
我会调查一下。错误确实是在7月1日之后开始出现的,这些机器使用NTP。 - 101100
所以这个 bug 是一个非常好的候选。重新启动服务器应该可以解决你的问题。 - Jean-Philippe Briend
今天我成功获得了物理访问权限,重新启动了机器,问题得到了解决。 - 101100

3
如果您的服务器使用NTP(正如您所提到的),并且CPU使用率达到100%,请检查您的中是否存在Clock: inserting leap second 23:59:60 UTC,如果找到,则可以确定您的服务器受到了Leap Second bug的影响,不幸的是,Java最受影响。
为了解决这个问题,而无需重新启动任何服务器(例如tomcat),请运行以下命令。
/etc/init.d/ntp stop
date `date +"%m%d%H%M%C%y.%S"` 

希望这可以帮助到您。

很遗憾,我没有root访问权限尝试这个解决方案。 - 101100

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接