And*_*rke 14 java junit multithreading
我正在尝试编写一个需要多线程的单元测试.但是,似乎线程只是停止执行的一部分.请考虑以下代码:
public class Test {
@org.junit.Test
public void TestThreads() {
new Thread(new Runnable() {
public void run() {
for (int i = 1; i < 1000; i++) System.out.println(i);
}
}).start();
}
}
Run Code Online (Sandbox Code Playgroud)
如果我运行此单元测试,它通常会停止在140-180之间显示输出.如果我将此代码转换为常规类并运行它,它可以正常工作.有没有人知道我在这里缺少什么?
谢谢, - 安德鲁.
Mar*_*lis 24
您可以使用它Thread.join()来防止测试在新线程完成其任务之前完成:
@org.junit.Test
public void TestThreads() throws InterruptedException {
Thread t = new Thread(new Runnable() {
public void run() {
for (int i = 1; i < 1000; i++) System.out.println(i);
}
});
t.start();
t.join();
}
Run Code Online (Sandbox Code Playgroud)
通常,JVM将在最后一个非守护程序线程终止时终止.您可能希望简单地调用t.setDaemon(false)该线程会阻止JVM在任务完成之前退出.但是,当主线程完成时,junit将调用 System.exit().
正如Gus在评论中指出:"你需要join(),因为start()不会阻止".
他是对的,你也可以打电话给run()这个最小的例子.但是,我假设您正在启动一个线程,因为您希望它与另一个线程并发运行.调用run()一个Thread被FindBugs标记为可能的错误 - 如果你只是打算调用run(),你可能只想实现Runnable而不是使用Thread.
在TestThread函数中,JUnit无法告诉您生成了一个新线程.一旦函数结束(到达最后一行)并且不知道线程,它就会回收它在函数中创建的任何对象.
因此,您可以看到Thread的输出,直到它被杀死.如果要等待线程完成,可以使用Thread.join(在调用之后Thread.start())使其等待结果或使用wait-notify某个对象.
此外,发现了这个问题:JUnit终止子线程
运行测试的父线程可能正在完成。如果可以避免它,那么就不要在测试中创建新线程。我将创建一个实现可运行的新类,然后在该对象上简单地调用 run 来测试该类。您不需要在测试中测试线程调度。希望 Java 语言开发团队能够解决这个问题:)