Java:线程中的Thread.sleep():没有等待

jac*_*k-y 4 java junit multithreading sleep

线程没有睡觉我有问题.
我不能把我的整个代码放在这里.所以,为了重现,这里是一个等待5秒的基本代码.

try {
    int millisec = 5000;
    System.out.println(new Date());
    System.out.println("We wait " + millisec + " milliseconds");
    Thread.sleep(millisec);
    System.out.println(new Date());
} catch (Exception e) {
    e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)

输出:

星期四8月22日20:01:42 CEST 2013
我们等待5000毫秒
Thu Aug 22 20:01:47 CEST 2013

一切都好.
但是当我把这段代码放在一个线程中时,没有睡觉.此代码示例:

try {
    Thread aThread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                int millisec = 5000;
                System.out.println(new Date());
                System.out.println("We wait " + millisec + " milliseconds");
                Thread.sleep(millisec);
                System.out.println(new Date());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
    aThread.start();
} catch (Exception e) {
    e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)

输出:

Thu Aug 22 20:07:30 CEST 2013
我们等待5000毫秒

......没有别的,线程终止了.
我不明白为什么.请问,有什么想法吗?

编辑:我使用Eclipse和JUnit进行测试.

Gra*_*ray 5

编辑:

问题是JUnit的工作原理.它不知道后台线程是如何产生的,所以当测试线程完成时,它会杀死其余的线程而不等待它们.


当我在一个小类中尝试时,你的代码会正确地吐出两个日期行main().以下是您在应用程序中看不到输出的原因:

  • 产生它的线程aThread可能是一个守护程序线程本身.该aThread所以因为它的后台程序状态从产卵线程的状态得到的守护进程.如果JVM 第二次之前完成System.out.println(...),aThread则会被杀死.如果对此有疑问,您应该:

    Thread aThread = new Thread(new Runnable() {
    ...
    // ensure the deamon flag is off _before_ we start the thread
    aThread.setDaemon(false);
    aThread.start();
    
    Run Code Online (Sandbox Code Playgroud)
  • 另一种可能性是某些东西实际上在第二天System.out之前关闭println(...);.不太可能,但可能.您是否正在使用关机挂钩进行清理?

  • 第三种可能性是输出实际上正在打印,但您的IDE或控制台在某种程度上不显示输出.

  • 另一种可能性是System.out.println(...);扔了一个IOException.这可能是有趣的检查值System.out.checkError()看它是否是true,虽然我不知道你会怎么然后显示它.

要尝试的一件事是创建一个临时文件而不是打印输出.就像是:

new File("/var/tmp/" + System.currentTimeMillis()).createNewFile();
Run Code Online (Sandbox Code Playgroud)

然后你应该看到2个文件"/var/tmp"(或OS上的临时目录).

您还应该尝试更改System.outSystem.err查看是否更改了任何内容.令人怀疑,但值得一试.

如果这些不能正常工作,那么有些东西会强行杀死JVM,因此无法等待后台线程.