线程中的Java:Thread.sleep():无等待
我有一个线程不睡眠的问题。线程中的Java:Thread.sleep():无等待,java,multithreading,junit,sleep,Java,Multithreading,Junit,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()); }
我不能把我的全部密码都放在这里。所以,为了重现,这里有一个等待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();
}
输出:
2013年8月22日星期四20:01:42 CEST我们等待5000毫秒
2013年8月22日星期四20:01:47 CEST
一切正常。
但是当我把这个代码放在一个线程中,没有睡眠。此代码的示例:
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();
}
输出:
2013年8月22日星期四20:07:30 CEST我们等待5000毫秒
…除此之外,线程被终止。
我不明白为什么。拜托,有什么想法吗 编辑:我使用Eclipse和JUnit进行测试。编辑: 问题是JUnit是如何工作的。它不知道后台线程已经生成,所以当测试线程完成时,它会杀死其余线程而不等待它们
当我在一个小的
main()
类中尝试时,您的代码正确地吐出了两个日期行。以下是一些可能的原因,说明您在应用程序中看不到输出的原因:
- 生成aThread的线程本身可能是守护进程线程。因此,
是守护进程,因为它的守护进程状态是从生成线程的状态获取的。如果JVM在第二个aThread
之前完成,则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();
- 另一种可能性是,在第二个
println(…)之前,实际上有东西正在关闭
代码>。不太可能,但可能。您是否使用关机挂钩进行清理System.out
- 第三种可能是输出实际上正在打印,但IDE或控制台不知何故没有显示输出
- 另一种可能性是,
System.out.println(…)代码>引发了一个
。检查IOException
的值以查看它是否为System.out.checkError()
,这可能很有趣,尽管我不确定接下来如何显示它true
new File("/var/tmp/" + System.currentTimeMillis()).createNewFile();
然后您应该在“/var/tmp”
(或操作系统上的临时目录)中看到2个文件
您还应该尝试将System.out
更改为System.err
,以查看是否有任何更改。怀疑但值得一试
如果这些都不能很好地工作,那么JVM将被强制杀死,因此它无法等待后台线程。我认为您没有在主线程中调用join()(如果您使用JUnit,那么线程将调用测试用例并创建线程对象) 你的进程本身是否在5秒后仍然有效?你的代码对我有效。你确定你的IDE没有切断输出或其他什么吗?对我来说也很有效,清理后再试一次。这应该不是必要的,但为了安全起见,试着在睡眠后添加一些println语句(只是打印一堆垃圾)。也许您的控制台出于某种原因正在缓冲输出。我使用Eclipse和Junit进行测试。如果您觉得合适,问题出在我的IDE中。我来看看。谢谢你的及时回复!可能性1:aThread.setDaemon(false)添加,对我来说没有更改。可能性3:是的,我使用Eclipse和JUnit,这可能是原因。谢谢实际上还有另一种(不太可能的)可能性:一个
错误
被抛出到某个catch(异常e)
没有捕获到的地方,线程被终止得非常好@Katona。不太可能,但可能。System.out.println(…)
可能还引发了一个正在捕获和阻止的内部异常。我加了一个,还有一个。如果使用JUnit4@Test(timeout=…)
或timeout
规则,则基于整个测试用例在守护进程线程中运行。您是对的,在启动后为JUnit测试添加aThread.join()
。不幸的是,我不能把它放在我的生产应用程序中。感谢您的帮助。Thread.join
如果您有一个工作线程,则可以使用其他类似的工具。