问题
在使用Junit测试时,发现在测试方法中启动新的线程,结果新开启的线程未执行,测试方法就结束了。难道Junit不支持多线程测试?
示例如下:
public class ThreadTest {
@Test
public void testSleep() {
Thread t = new Thread(()-> {
try {
Thread.sleep(1000);
} catch (Exception e) {
}
System.out.println("--------");
});
t.start();
System.out.println("end...");
}
}
第一想法就是 在junit中启动的线程都是daemon的?线程调用start() 方法后是不能修改线程的daemon状态的。
还可能一种可能就是,执行完主线程后就直接System.exit() 退出jvm。
下面我们分析下源码,看看到底是什么情况
Debug模式下运行 testSleep() 方法,如下:
通过 Junit 运行 testSleep() 方法,我们发现Junit的运行启动主类:
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.java
执行的方法 RemoteTestRunner.main(String arg[])
RemoteTestRunner.main() 源码分析
public static void main(String JavaDoc[] args) {
try {
RemoteTestRunner testRunServer= new RemoteTestRunner();
testRunServer.init(args);
testRunServer.run();
} catch (Throwable JavaDoc e) {
e.printStackTrace(); // don't allow System.exit(0) to swallow exceptions
} finally {
// fix for 14434
System.exit(0);
}
}
从代码中我们发现,当执行完testSleep()方法的主线程时,就会调用 finally里面的 System.exit(0) 方法,让JVM强制退出。这是在testSleep()方法中启动的新线程也就强制停止了,而不会打印线程中输出的信息。
解决办法
最简单的解决办法如下:
@Test
public void testSleep() throws InterruptedException {
Thread t = new Thread(()-> {
try {
Thread.sleep(1000);
} catch (Exception e) {
}
System.out.println("--------");
});
t.start();
System.out.println("end...");
t.join();
// TimeUnit.SECONDS.sleep(1000);
}
也可以使用 FutrueTask、CountDownLatch等。
想了解更多精彩内容请关注我的公众号
网友评论