如果在Junit测试中,为什么非daemon线程终止?

发布于 2025-02-11 04:22:42 字数 2224 浏览 1 评论 0原文

以下守护进程 - 比恩正在运行:

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;
            }
        }

    }
}

这是守护程序,如果辛格尔顿(Singleton)终止。

因此,以下非daemon豆在等他:

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");

    }

}

beans的弹簧配置是:

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

    <bean id="waitor" class="beans.Waitor1">
        <property name="joinable" ref="daemon"/>
    </bean>

问题是:如果从Main运行而且如果从Junit Test运行不起作用,为什么它可以正常工作?

运行代码是

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

@Test
    public void testWaiting1() {
        new ClassPathXmlApplicationContext("/beans/Waiting1.xml");
    }

在Main中,我会看到所有HearBeats。在Junit的情况下,我只看到心跳0,然后消息“等待开始”,并且程序被终止,就好像没有人在这里等着非daemon线程一样。

它的原因是什么?

The following daemon-bean is running:

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;
            }
        }

    }
}

It is daemon, so would terminate if singleton.

So, the following non-daemon bean is waiting for him:

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");

    }

}

The Spring configuration for beans is:

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

    <bean id="waitor" class="beans.Waitor1">
        <property name="joinable" ref="daemon"/>
    </bean>

The question is: why is it working if runned from main and not working if ran from jUnit test?

Running code is

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

or

@Test
    public void testWaiting1() {
        new ClassPathXmlApplicationContext("/beans/Waiting1.xml");
    }

In case of main I see all hearbeats. In case of jUnit I see only heartbeat 0, then message "Waiting started" and the program is terminated as if nobody waiting for non-daemon threads here.

What can be the reason of it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

晨敛清荷 2025-02-18 04:22:43

当您从main运行代码时,它会创建两个bean,因此两个线程 - 守护程序和非daemon。只要非daemon线程正在运行,您的应用程序就不会退出。因此起作用。

从Junit跑时,情况有所不同。 Junit测试方法完成(春季上下文开始后立即完成),Junit假设您的测试已完成。因此,它杀死了您的所有线程,基本上是整个JVM。

请记住您的Witeor1 Bean产生了Junit不在乎的背景线程。一旦您离开@Test方法,方法将停止一切。

When you run your code from main it creates both beans, thus two threads - daemon and non-daemon. As long as non-daemon thread is running, your application won't exit. So it works.

It's different when run from JUnit. As soon as JUnit test method completes (and it completes immediately after the Spring context is up), JUnit assumes your tests are done. Thus it kills all your threads and basically the whole JVM.

Remember your Waitor1 bean spawns a background thread which JUnit doesn't care about. As soon as you leave @Test method JUnit will just stop everything.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文