2012-02-29 97 views
1

我有一個JMS客戶端這是使用下面的代碼消耗從隊列中的消息:連接關閉不返回

try { 

     ... 

     FileUtils.writeStringToFile(getNextFile(), txtMessage.getText());     

    } catch (JMSException e) { 
     LOG.error(e.getMessage());   
    } catch (IOException e) { 
     LOG.error(e.getMessage());   
    }finally{ 
     if(this.openMessages<=0){ 
      try { 
       if(transacted){ 
        session.commit(); 
        LOG.info("Session commited"); 
       } 

       consumer.close();   

//    System.exit(0);    
       closeSession();     

       System.exit(0); 
      } catch (JMSException e) { 
       LOG.error("Error while closing the consumer and session.", e); 
      } catch (Exception e2) { 
       LOG.error("Global Exception while closing the consumer and session.", e2); 
      }   
     }   
    } 

public void closeSession() throws JMSException { 
    if (connection != null) { 
     connection.stop(); 
     connection.close(); 
    } 
} 

關閉後消費我想關閉會話。爲了關閉它,一個叫做closeSession的方法停止了連接並關閉它。不幸的是,由於某種原因,有時候,調用close不會返回。因此,我在上面的代碼片段中添加了一條exit語句(現在已註釋)。繼接口文檔後,我們有:

當調用此方法時,它應該不會返回,直到消息處理已按順序關閉。這意味着所有可能已經運行的消息監聽器都已經返回,並且所有待處理的接收都已經返回。

這不是我的情況,因爲我知道所有的消息都已被處理。

任何提示爲什麼這是有時不工作?

+1

當close()被阻塞時,你可以做線程轉儲嗎? 'jstack' /'jconsole'或者JVisualVM會做到這一點。 – 2012-02-29 10:24:16

回答

0

我看不到在您的代碼中調用System.exit(0)的原因。

我看到很多代碼阻止的東西,但我沒有看到任何處理。

你正在推翻這一點。與我過去的做法相比,你的MessageListener看起來太複雜了。我會簡化。偵聽器不必消失並且覈對它正在運行的JVM。它所要做的就是完成,關閉它的連接,並讓應用服務器將它放回池中,等待下一條消息到達隊列中。