我對Tomcat並不是很熟悉,在我的腦海中,它基本上被抽象爲一個cgi服務器,它可以在調用之間保存JVM - 但我知道它可以做的遠不止這些。Tomcat servlet應用程序的後臺線程
我正在尋找一種方式Tomcat服務器啓動時啓動背景線程,這將定期更新服務器環境(在我的這個特殊的情況是聽一些其他服務和更新的可用性,心跳線程信息,但人們可以想象它有多種用途)。
有沒有一個標準的方法來做到這一點? Context的啓動和更新/查詢都是?
任何指向相關文檔和/或代碼示例的指針都將非常感謝。
我對Tomcat並不是很熟悉,在我的腦海中,它基本上被抽象爲一個cgi服務器,它可以在調用之間保存JVM - 但我知道它可以做的遠不止這些。Tomcat servlet應用程序的後臺線程
我正在尋找一種方式Tomcat服務器啓動時啓動背景線程,這將定期更新服務器環境(在我的這個特殊的情況是聽一些其他服務和更新的可用性,心跳線程信息,但人們可以想象它有多種用途)。
有沒有一個標準的方法來做到這一點? Context的啓動和更新/查詢都是?
任何指向相關文檔和/或代碼示例的指針都將非常感謝。
如果您希望在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) {
}
}
}
啊!謝謝,這非常簡單。 我正確地說「ServletContext」是我需要修改的,讓這個線程將信息傳遞給我的servlet,因此它可以使用我的心跳監聽器收集的狀態? – SquareCog 2009-04-27 01:52:56
是的,在我的答案中錯過了這部分。 :) ServletConext可以從ServletContextEvent中獲得,它可以傳遞給你的Thread對象,它可以獲取/設置所有線程的屬性。 – 2009-04-27 02:07:39
那時,如何訪問`MyServletContextListener`來查詢線程? – 2016-11-23 15:04:44
我正在尋找一種方式來啓動一個後臺線程,當一個Tomcat服務器啓動
我想你正在尋找一種啓動後臺線程的方式,你的web應用程序由Tomcat啓動。
這可以使用ServletContextListener來完成。它在web.xml中註冊,並且會在您的應用程序啓動或停止時調用。然後,您可以使用普通的Java方法創建(並稍後停止)線程,以創建線程(或ExecutionService)。
啊,克里斯擊敗了我.. – Thilo 2009-04-27 01:49:05
我只是對克里斯給出的非常詳細的答案做一個小小的修改;我將myThread
設置爲一個Daemon線程myThread.setDaemon(true);
,只要您有其他非守護線程工作需要您的後臺線程,它就會基本保持線程處於活動狀態。當所有這些線程完成後,您的守護程序線程將被JVM停止,您不需要在contextDestroyed
中自行處理它。 但這只是我的2美分。
將<load-on-startup>1</load-on-startup>
置於您的web.xml中的<servlet>
塊中會迫使您的servlet的init()
在Tomcat啓動後立即發生,而不是等待第一個請求到達。如果你想從init()
產生後臺線程,這很有用。
另一種方法,如果您使用基於彈簧的框架,您可以指定要在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();
}
}
值得注意的是,當你想要的時候,你通常可以啓動一個線程,如果有比上下文初始化更方便的地方。例如。它可能在特定servlet的init方法中,或者當某個類首先被初始化等。 – 2009-04-27 05:34:36