线程没有睡觉我有问题 我不能把我的整个代码放在这里。所以,为了重现,这里是一个等待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();
}
输出:
Thu Aug 22 20:01:42 CEST 2013
我们等待5000毫秒
8月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();
}
输出:
Thu Aug 22 20:07:30 CEST 2013
我们等待5000毫秒
......没有别的,线程终止了。
我不明白为什么。请问,有什么想法吗?
编辑:我使用Eclipse和JUnit进行测试。
答案 0 :(得分: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();
另一种可能性是,在第二个System.out
之前,某些内容实际上正在关闭println(...);
。不太可能,但可能。您是否正在使用关闭挂钩进行清理?
第三种可能性是输出实际上正在打印,但您的IDE或控制台在某种程度上不显示输出。
另一种可能性是System.out.println(...);
投掷IOException
。检查System.out.checkError()
的值以查看它是否为true
可能会很有趣,但我不确定您将如何显示它。
要尝试的一件事是创建一个临时文件而不是打印输出。类似的东西:
new File("/var/tmp/" + System.currentTimeMillis()).createNewFile();
然后你应该看到"/var/tmp"
中的2个文件(或者操作系统上的临时目录所在的位置)。
您还应该尝试将System.out
更改为System.err
,看看是否会发生任何变化。令人怀疑,但值得一试。
如果这些不能正常工作,那么有些东西会强行杀死JVM,因此无法等待后台线程。
答案 1 :(得分:1)
嗯,我认为你没有在你的主线程中调用join()(如果你使用JUnit,那么线程调用测试用例并创建线程对象)。