Javaでの信号処理

私は、ある種のJavaサービスを作成するタスクにしばしば直面しました。 ほとんどの場合、OSとしてLinuxを使用しているため、このようなサービスを管理するのが最も便利です。デーモンと同様にサービスを操作するのが最も便利です。 つまり、次を実行します。

start-stop-daemon --start --make-pidfile --pidfile /var/run/myservice.pid --exec / usr / bin / java--jar myservice.jar


、停止:

start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/myservice.pid


--stopコマンドはSIGTERMシグナルをJVMに送信し、サービスが停止します。 サービスの完了時にアクションを実行する必要がない限り、すべてが悪くないかのように、JVMは正常に完了します。 たとえば、リソースを明示的に解放したり、stdoutで何かいいことを書いたりします。



しかし、1.3.1以降のJVMではシグナルを処理できるため、すべてがそれほど怖いわけではありません。 答えとして-habrakatの下で。



信号を処理するために、私はかつて簡単なヘルパークラスを作成しました。

import sun.misc.Signal;

import sun.misc.SignalHandler;



public class DiagnosticSignalHandler implements SignalHandler {



// Static method to install the signal handler

public static void install(String signalName, SignalHandler handler) {

Signal signal = new Signal(signalName);

DiagnosticSignalHandler diagnosticSignalHandler = new DiagnosticSignalHandler();

SignalHandler oldHandler = Signal.handle(signal, diagnosticSignalHandler);

diagnosticSignalHandler.setHandler(handler);

diagnosticSignalHandler.setOldHandler(oldHandler);

}

private SignalHandler oldHandler;

private SignalHandler handler;



private DiagnosticSignalHandler() {

}



private void setOldHandler(SignalHandler oldHandler) {

this .oldHandler = oldHandler;

}



private void setHandler(SignalHandler handler) {

this .handler = handler;

}



// Signal handler method

@Override

public void handle(Signal sig) {

System. out .println( "Diagnostic Signal handler called for signal " + sig);

try {

handler.handle(sig);



// Chain back to previous handler, if one exists

if (oldHandler != SIG_DFL && oldHandler != SIG_IGN) {

oldHandler.handle(sig);

}



} catch (Exception e) {

System. out .println( "Signal handler failed, reason " + e);

}

}

}




* This source code was highlighted with Source Code Highlighter .






使用例:

import sun.misc.Signal;

import sun.misc.SignalHandler;



public class App {

private SomeVeryImportantResource resource;



public static void main(String[] args) {

SignalHandler signalHandler = new SignalHandler() {

@Override

public void handle(Signal sig) {

...

resource.release();

...

}

};

DiagnosticSignalHandler.install( "TERM" , signalHandler);

DiagnosticSignalHandler.install( "INT" , signalHandler);

DiagnosticSignalHandler.install( "ABRT" , signalHandler);

...

resource. lock ();

...

}

}




* This source code was highlighted with Source Code Highlighter .






それだけです、複雑なことは何もありません。 ハンドラーで必要なアクションを実行すると、アプリケーションが終了します。



このトピックでは、最も単純なユースケースを示しました-SIGINT、SIGTERM、およびSIGABRTをキャッチします。 実際、はるかに多くの異なる種類の信号、およびそれらの使用オプションがあります。 ここで詳細な説明を参照してください。

http://www.ibm.com/developerworks/ibm/library/i-signalhandling/



All Articles