5

次のデーモン 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>

問題は、メインから実行すると機能し、jUnit テストから実行すると機能しないのはなぜですか?

実行中のコードは

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

また

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

メインの場合、すべてのハートビートが表示されます。jUnit の場合、ハートビート 0 のみが表示され、「待機中」というメッセージが表示され、デーモン以外のスレッドを誰も待っていないかのようにプログラムが終了します。

その理由は何ですか?

4

1 に答える 1

9

コードを実行するmainと、両方の Bean が作成されるため、デーモンと非デーモンの 2 つのスレッドが作成されます。非デーモン スレッドが実行されている限り、アプリケーションは終了しません。それでうまくいきます。

JUnit から実行する場合は異なります。JUnit テスト メソッドが完了するとすぐに (Spring コンテキストが起動した直後に完了すると)、JUnit はテストが完了したと見なします。したがって、すべてのスレッドと基本的に JVM 全体を強制終了します。

Waitor1Bean は、JUnit が気にしないバックグラウンド スレッドを生成することを思い出してください。メソッドを終了するとすぐに、@TestJUnit はすべてを停止します。

于 2012-11-25T12:25:04.190 に答える