第12 回 イベント処理
今回は、EeB内で話題となっていたタイマー処理を実現すべく、 イベント処理について考えようと思います。
イベントという言葉はGUIプログラムをしたことがある人はおなじみかもしれません。
しかし、JavaのWebシステム開発ではあまり聴かない言葉ではないでしょうか?
イベントとは「オブジェクトに特定の現象が発生した時に発する信号」です。
イベントを使った処理とは、「オブジェクトに特定の現象が発生した時に処理を行う」事です。
つまり、オブジェクトから何らかの報告を受け、それに応じて処理を行います。
ここだけを見れば、以前書かせていただいた スレッドのwaitメソッドを利用した待ち合わせ処理 に似ています。
しかし、スレッドのwaitメソッドは処理を待つのに対してイベント処理は 待ちません。動きながらイベントが発生すれば処理を行うのです。
今回は、頭で書いたようにタイマーを実装してみました。
スタートメソッドを実行すると一定の間隔でイベントを発生します。
以下はタイマークラスです。
後に使用サンプルがあります…。
public class Timer { private long interval = 1000; // イベント発生間隔 private Status status = Status.OFF; // 状態 private Object listener = null; // イベントオブジェクト private String methodName = null; // イベントメソッド private Thread eventThread = null; // イベント発生スレッド //================================================== // メソッドの登録 //================================================== public void setEventListener(Object listener, String methodName) { this.listener = listener; this.methodName = methodName; } //================================================== // イベント発生間隔 //================================================== public long getInterval() { return interval; } public void setInterval(long interval) { this.interval = interval; } //================================================== // 状態 //================================================== public Status getStatus() { return status; } //================================================== // タイマー開始 //================================================== public void start() { // 状態をONにする status = Status.ON; // イベントを発生 // (メインスレッドで実行することで確実に1回は実行する) if (methodName != null) { try { Method method = listener.getClass() .getMethod(methodName, new Class[0]); method.invoke(listener, new Object[0]); } catch (Exception e) { e.printStackTrace(); } } // スレッド定義 eventThread = new Thread(){ public void run() { try { // 状態がONの間、繰り返す while (status.equals(Status.ON)) { // 一定間隔待ち synchronized (this) { long eventTime = System.currentTimeMillis() + interval; while (System.currentTimeMillis() < eventTime) { this.wait(eventTime - System.currentTimeMillis()); } } // 他スレッドからの変更を受ける Thread.yield(); // イベント発生前にもう一度、状態をチェック if (!status.equals(Status.ON)) { break; } // イベント発生 if (methodName != null) { try { Method method = listener.getClass() .getMethod(methodName, new Class[0]); method.invoke(listener, new Object[0]); } catch (Exception e) { e.printStackTrace(); } } } } catch (Exception e) { e.printStackTrace(); } } }; // スレッドスタート eventThread.start(); } //================================================== // タイマー停止 //================================================== public void stop() { status = Status.OFF; // タイマースレッドが終わるまで待つ try { eventThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } //************************************************** // タイマーの状態 //************************************************** public enum Status { ON, OFF } }
以下、使用サンプルです。
public class Test { //================================================== // メイン //================================================== public static void main(String[] args) { // タイマーオブジェクト生成 Timer t = new Timer(); // イベントメソッドを登録 t.setEventListener(new Test(), "timer"); // イベントの発生間隔を設定 t.setInterval(2000); // タイマースタート System.out.println("Start"); t.start(); // 10秒待つ try { Thread.sleep(10000); } catch (InterruptedException e) { } // タイマー終了 t.stop(); System.out.println("End"); } //================================================== // タイマーイベント //================================================== public static void timer() { System.out.println("イベント発生:" + System.currentTimeMillis() + "ms"); } }
肉の食べられるイベント歓迎中!!!