以下守护程序 bean 正在运行:
public class DaemonBean extends Thread {
private final static Logger log = LoggerFactory.getLogger(DaemonBean.class);
{
setDaemon(true);
start();
}
@Override
public void run() {
for(int i=0; i<10 && !isInterrupted(); ++i) {
log.info("Hearbeat {}", i);
try {
sleep(1000);
} catch (InterruptedException e) {
return;
}
}
}
}
它是守护进程,所以如果是单例就会终止。
因此,下面的非守护程序 bean 正在等待他:
public class Waitor1 extends Thread {
private final static Logger log = LoggerFactory.getLogger(Waitor1.class);
private Thread joinable;
{
setDaemon(false);
setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
log.error("Error in thread", e);
}
});
}
public Thread getJoinable() {
return joinable;
}
public void setJoinable(Thread value) {
this.joinable = value;
if( this.joinable != null ) {
start();
}
}
@Override
public void run() {
log.info("Waiting started");
try {
joinable.join();
} catch (InterruptedException e) {
log.info("Thread interrupted");
return;
}
log.info("Waiting ended");
}
}
bean 的 Spring 配置是:
<bean id="daemon" class="beans.DaemonBean"/>
<bean id="waitor" class="beans.Waitor1">
<property name="joinable" ref="daemon"/>
</bean>
问题是:为什么如果从 main 运行它就可以工作,而如果从 jUnit 测试运行就不能工作?
运行代码是
public static void main(String[] args) {
new ClassPathXmlApplicationContext("/beans/Waiting1.xml");
}
或
@Test
public void testWaiting1() {
new ClassPathXmlApplicationContext("/beans/Waiting1.xml");
}
在 main 的情况下,我看到所有的心跳。在 jUnit 的情况下,我只看到心跳 0,然后是消息“等待开始”,程序终止,就好像没有人在这里等待非守护线程一样。
这可能是什么原因?
最佳答案
当您从 main
运行代码时,它会创建两个 bean,因此会创建两个线程 - 守护进程和非守护进程。只要非守护线程在运行,您的应用程序就不会退出。所以它有效。
从 JUnit 运行时不同。一旦 JUnit 测试方法完成(并且它在 Spring 上下文启动后立即完成),JUnit 就会假定您的测试已完成。因此,它会杀死您的所有线程,基本上会杀死整个 JVM。
请记住您的 Waitor1
bean 会生成一个 JUnit 不关心的后台线程。只要你离开 @Test
方法,JUnit 就会停止一切。
关于java - 为什么非守护线程在 jUnit 测试中终止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13550922/