如果在jUnit测试中,为什么非守护程序线程正在终止?

Suz*_*ioc 4 java spring multithreading jvm daemon

以下守护程序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;
            }
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

它是守护进程,所以如果单身就会终止.

所以,以下非守护进程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");

    }

}
Run Code Online (Sandbox Code Playgroud)

Bean的Spring配置是:

<bean id="daemon" class="beans.DaemonBean"/>

    <bean id="waitor" class="beans.Waitor1">
        <property name="joinable" ref="daemon"/>
    </bean>
Run Code Online (Sandbox Code Playgroud)

问题是:如果从jUnit测试运行,为什么它从main运行而不工作?

运行代码是

 public static void main(String[] args) {
        new ClassPathXmlApplicationContext("/beans/Waiting1.xml");
    }
Run Code Online (Sandbox Code Playgroud)

要么

@Test
    public void testWaiting1() {
        new ClassPathXmlApplicationContext("/beans/Waiting1.xml");
    }
Run Code Online (Sandbox Code Playgroud)

在主要的情况下,我看到所有的听力.在jUnit的情况下,我只看到心跳0,然后消息"等待开始",程序终止,好像没有人在这里等待非守护进程线程.

它可能是什么原因?

Tom*_*icz 6

当您从中运行代码时,main会创建两个bean,从而创建两个线程 - 守护进程和非守护进程.只要非守护程序线程正在运行,您的应用程序就不会退出.所以它有效.

从JUnit运行时会有所不同.一旦JUnit测试方法完成(并且它在Spring上下文启动后立即完成),JUnit就会假定您的测试已完成.因此它会杀死所有线程,基本上杀死整个JVM.

记住你的Waitor1bean会生成一个JUnit不关心的后台线程.一旦你离开@Test方法,JUnit就会停止一切.