jms defaultmessagelistenercontainer无法在spring应用程序上下文中关闭close()

sirbozc5  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(484)

我正在使用spring集成收听solace动态主题,如下所示:

<int-jms:message-driven-channel-adapter
    id="myJmsAdapter" channel="receiveChannel" container="jmsContainer" />

<bean id="jmsContainer"
    class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="solaceConnectionFactory" />
      <property name="destinationName" value="${my.topic}/#{main.getCar_type_value()}" />
    <property name="pubSubDomain" value="true" />        
    <property name="sessionTransacted" value="false" />

</bean>

我能够倾听主题、理解信息并处理它。但关于 System.exit(0) ,即使spring应用程序上下文在shutdownhook中关闭,jms侦听器线程仍处于挂起状态,无法正常关闭:

ctxt.registerShutdownHook();
...
  trigger = new ShutdownTrigger(maxWaitForResponseMillis, ctxt);
  trigger.startShutdownTimer();

    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
            log.info("Exiting Main Thread!");
            ctxt.close();
        }
    });

应用程序在超时时正确关闭,但当我尝试在使用system.exit(0)从其他类退出计时器之前退出时,它不会关闭,线程挂起。
定时器功能如下:

public void startShutdownTimer() {
      timer.schedule(new TimerTask() {
        @Override
        public void run() {
            log.info("Timer max wait has elapsed - triggering graceful 
     shutdown");

            // perform some task here on timeout..
            }
            log.info("Returning with exit code: " + exitCode);

            System.exit(exitCode); //this one works and it properly shutsdown
        }
    }, maxWaitForResponseMillis);
}

我还尝试在关闭主类的上下文之前添加timer.cancel,如下所示,但没有成功:

Runtime.getRuntime().addShutdownHook(new Thread() {
    public void run() {
    log.info("Cancelling current timer task..")
        trigger.getTimer().cancel(); //it didnt work and the thread still hangs
        log.info("Exiting Main Thread!");
        ctxt.close();
    }
});

我试着取出timer函数和它的所有引用,看看是不是这个timer线程导致了这个问题,但是没有。。即使删除了计时器任务,应用程序也会挂起。
下面是挂起时的线程堆栈:

"Thread-3" #26 prio=5 os_prio=0 tid=0x00007fcf48024800 nid=0x60ad in Object.wait() [0x00007fd026ef1000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at org.springframework.jms.listener.DefaultMessageListenerContainer.doShutdown(DefaultMessageListenerContainer.java:568)
- locked <0x00000000ee0c9ec0> (a java.lang.Object)
at org.springframework.jms.listener.AbstractJmsListeningContainer.shutdown(AbstractJmsListeningContainer.java:237)

请帮忙找出问题和解决办法。。。

bfhwhh0e

bfhwhh0e1#

你在打电话吗 System.exit() 在侦听器容器线程上

"jmsContainer-1" #24 prio=5 os_prio=0 tid=0x00007fdbd8e50800 nid=0xb77 in Object.wait() [0x00007fdb9f1bc000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000000f02cfb68> (a com.tdsecurities.fxts.vs.FxVsCashBalanceApp$1)
    at java.lang.Thread.join(Thread.java:1245)
    - locked <0x00000000f02cfb68> (a com.tdsecurities.fxts.vs.FxVsCashBalanceApp$1)
    at java.lang.Thread.join(Thread.java:1319)
    at java.lang.ApplicationShutdownHooks.runHooks(ApplicationShutdownHooks.java:106)
    at java.lang.ApplicationShutdownHooks$1.run(ApplicationShutdownHooks.java:46)
    at java.lang.Shutdown.runHooks(Shutdown.java:123)
    at java.lang.Shutdown.sequence(Shutdown.java:167)
    at java.lang.Shutdown.exit(Shutdown.java:212)
    - locked <0x00000000c04335c8> (a java.lang.Class for java.lang.Shutdown)
    at java.lang.Runtime.exit(Runtime.java:109)
    at java.lang.System.exit(System.java:971)

这会导致应用程序上下文(thread-3和thread-5)中出现死锁(关闭容器)。
你可能需要把枪放下 System.exit() 调用另一个线程,但我需要知道您正在使用哪个版本的spring进行进一步分析。否则很难关联转储中的行号。

相关问题