2009-04-27 68 views
58

我對Tomcat並不是很熟悉,在我的腦海中,它基本上被抽象爲一個cgi服務器,它可以在調用之間保存JVM - 但我知道它可以做的遠不止這些。Tomcat servlet應用程序的後臺線程

我正在尋找一種方式Tomcat服務器啓動時啓動背景線程,這將定期更新服務器環境(在我的這個特殊的情況是聽一些其他服務和更新的可用性,心跳線程信息,但人們可以想象它有多種用途)。

有沒有一個標準的方法來做到這一點? Context的啓動和更新/查詢都是?

任何指向相關文檔和/或代碼示例的指針都將非常感謝。

+0

值得注意的是,當你想要的時候,你通常可以啓動一個線程,如果有比上下文初始化更方便的地方。例如。它可能在特定servlet的init方法中,或者當某個類首先被初始化等。 – 2009-04-27 05:34:36

回答

77

如果您希望在WAR部署啓動一個線程,可以在web.xml中定義一個上下文監聽器:

<web-app> 
    <listener> 
     <listener-class>com.mypackage.MyServletContextListener</listener-class> 
    </listener> 
</web-app> 

然後實現類是這樣的:

public class MyServletContextListener implements ServletContextListener { 

    private MyThreadClass myThread = null; 

    public void contextInitialized(ServletContextEvent sce) { 
     if ((myThread == null) || (!myThread.isAlive())) { 
      myThread = new MyThreadClass(); 
      myThread.start(); 
     } 
    } 

    public void contextDestroyed(ServletContextEvent sce){ 
     try { 
      myThread.doShutdown(); 
      myThread.interrupt(); 
     } catch (Exception ex) { 
     } 
    } 
} 
+0

啊!謝謝,這非常簡單。 我正確地說「ServletContext」是我需要修改的,讓這個線程將信息傳遞給我的servlet,因此它可以使用我的心跳監聽器收集的狀態? – SquareCog 2009-04-27 01:52:56

+1

是的,在我的答案中錯過了這部分。 :) ServletConext可以從ServletContextEvent中獲得,它可以傳遞給你的Thread對象,它可以獲取/設置所有線程的屬性。 – 2009-04-27 02:07:39

+0

那時,如何訪問`MyServletContextListener`來查詢線程? – 2016-11-23 15:04:44

12

我正在尋找一種方式來啓動一個後臺線程,當一個Tomcat服務器啓動

我想你正在尋找一種啓動後臺線程的方式,你的web應用程序由Tomcat啓動。

這可以使用ServletContextListener來完成。它在web.xml中註冊,並且會在您的應用程序啓動或停止時調用。然後,您可以使用普通的Java方法創建(並稍後停止)線程,以創建線程(或ExecutionService)。

+1

啊,克里斯擊敗了我.. – Thilo 2009-04-27 01:49:05

2

我只是對克里斯給出的非常詳細的答案做一個小小的修改;我將myThread設置爲一個Daemon線程myThread.setDaemon(true);,只要您有其他非守護線程工作需要您的後臺線程,它就會基本保持線程處於活動狀態。當所有這些線程完成後,您的守護程序線程將被JVM停止,您不需要在contextDestroyed中自行處理它。 但這只是我的2美分。

5

<load-on-startup>1</load-on-startup>置於您的web.xml中的<servlet>塊中會迫使您的servlet的init()在Tomcat啓動後立即發生,而不是等待第一個請求到達。如果你想從init()產生後臺線程,這很有用。

1

另一種方法,如果您使用基於彈簧的框架,您可以指定要在beans.xml中初始化的類/線程。所以當tomcat啓動時,beans.xml將初始化它中提到的所有類。如果需要,您也可以傳遞構造函數參數。下面是同樣的例子。

的beans.xml

<bean id="monitoringSvc" class="com.mypackage.MonitoringService"> 
    <constructor-arg value="60"></constructor-arg> 
</bean> 

MonitoringService。java

public class MonitoringService{ 

    private MyThread myThread; 

    public MonitoringService(int seconds){ 
      myThread = new MyThread(seconds); 
      myThread.start(); 
    } 
}