第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");
}
}
肉の食べられるイベント歓迎中!!!

