2015年7月8日水曜日

Java で kill のシグナルを受け取ってみた

概要

Javaで kill の -HUP のシグナルを受け取れるみたいなので検証してみました

環境

Mac OS X 10.10.4
Eclipse Luna 4.4
Java 1.8.0_31

シグナルを受け付けるコードを作成

package test;

import java.util.Scanner;

public class Test {

    @SuppressWarnings("resource")
    public static void main(String[] args) throws InterruptedException {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> System.out.println("Run Shutdown Hook.")));
        System.out.println("Please send HUP signal.");
        while (true) {
            System.out.println("looping ...");
            Thread.sleep(5000);
        }
        // 以下のような入力を受け付ける処理でもOK
//      System.out.println("Please input.");
//      Scanner in = new Scanner(System.in);
//      String s = in.nextLine();
//      System.out.println(s);
    }
}

ポイントは1行で

Runtime.getRuntime().addShutdownHook(new Thread(() -> System.out.println("Run Shutdown Hook.")));

になります
上記の場合は HUP を受け取って終了する前にSystem.outを出力しています

動作を確認してみる

Eclipse 上で実行すると Eclipse の子プロセスとして実行されpidがわからないので java コマンドでターミナルから実行します
プロジェクトは普通の Java プロジェクトを想定しています

cd /path/to/project/bin
java test/Test

とすると無限ループがはじまります
この状態でpgrep javaでプロセス番号を調べてその番号を kill してみましょう

kill -HUP [process_number]

でこうすると無限ループが終了してSystem.outの内容が出力されます

$ java test/Test
Please send HUP signal.
looping ...
looping ...
Run Shutdown Hook.

とりあえずこれで Java 側でシグナルを受け取ることができました
addShutdownHookはメソッドもコールすることができるので別のメソッドをコールしてそっちの処理が終了するまでまた処理を続けることも可能です

最後に

これが何に使えるのかなというのを考えると

  • 無限ループに突入してしまった場合にHUP信号を外から送信して次の処理に進める
  • HUPしたタイミングで特定の処理(例えばロギング)を実行しその時の状況を把握する

とかとか
外部からシグナルを受け付けられる便利な機能なのでいろいろ考えられると思います

あと「java シグナル」とかで検索すると出てくる記事にsun.misc.Signalを使う方法が紹介されていますがどうやらsun.misc.Signalは非推奨もしくはなくなる可能性のあるクラスなので使わないほうがいいと思います

http://docs.oracle.com/javase/jp/6/api/java/lang/Runtime.html#addShutdownHook%28java.lang.Thread%29

0 件のコメント:

コメントを投稿