web-dev-qa-db-ja.com

Tomcatサーブレットアプリのバックグラウンドスレッド

私はTomcatにあまり馴染みがありませんが、私の頭の中では、呼び出し間でJVMを保存するcgiサーバーとして基本的に抽象化されていますが、それ以上のことができることはわかっています。

Tomcatサーバーの起動時にbackgroundスレッドを起動する方法を探しています。これにより、サーバーコンテキストが定期的に更新されます(特定の場合、これは他のサービスや更新からのハートビートをリッスンするスレッドです)可用性情報ですが、これにはさまざまな用途が考えられます)。

これを行う標準的な方法はありますか?コンテキストの起動と更新/クエリの両方?

関連するドキュメントやコードサンプルへのポインタをいただければ幸いです。

60
SquareCog

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) {
        }
    }
}
79
Chris Thornhill

Tomcatサーバーの起動時にバックグラウンドスレッドを起動する方法を探しています。

TomcatによってWebアプリケーションが起動されたときにバックグラウンドスレッドを起動する方法を探していると思います。

これは ServletContextListener を使用して実行できます。 web.xmlに登録され、アプリの起動または停止時に呼び出されます。その後、通常のJavaスレッド(またはExecutionService)を作成する方法を使用して、スレッドを作成(および後で停止)できます。

12
Thilo

Web.xmlの_<load-on-startup>1</load-on-startup>_ブロックに_<servlet>_を入れると、Tomcatの起動直後に、サーブレットのinit()が最初のリクエストの到着を待たずに強制的に発生します。これは、init()からバックグラウンドスレッドを生成する場合に便利です。

5
divbyzero

別の方法として、スプリングベースのフレームワークを使用している場合は、beans.xmlで初期化するクラス/スレッドを指定できます。そのため、Tomcatが起動すると、beans.xmlは、Tomcatに記載されているすべてのクラスを初期化します。必要に応じてコンストラクター引数を渡すこともできます。以下は同じ例です。

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();
     }
}    
2
Akshay

クリスが行った非常に詳細な回答に少し変更を加えるだけです。 myThreadmyThread.setDaemon(true);によってデーモンスレッドに設定すると、バックグラウンドスレッドを必要とする他の非デーモンスレッドが動作している限り、基本的にスレッドがアクティブになります。これらのスレッドがすべて終了すると、デーモンスレッドはJVMによって停止されるため、contextDestroyedで自分で処理する必要はありません。しかし、それはちょうど私の2セントです。

2
Ittai