Java Threadの中断と再開
Objectを動的に移動するために、スレッドの中断と再開について、いろいろ試してきました。
かつて(JDK1.1まで)では、stop, resume, suspend メソッドがあり、これらによってスレッド動作を制御できたが、現在のJDKではこれらのメソッドはすべて非推奨であり、インタプリタで実装もされていないところです。
では、どのようなメソッドが用意されているのか。
==============================================
その他の有益なメソッドには次のものがある。
Thread( String name )
コンストラクタ。引数に文字列を与えると、それがスレッドの名前になる。デバッグに便利。
boolean isAlive()
そのスレッドが生存しているかどうかを判定。
void join()
そのスレッドが終了するのを待ち合わせる。
static void sleep( long milisec )
クラスメソッドであり、指定ミリ秒間スリープする。スレッド実体とは直接関係なく、どんなプログラムでも使える(なぜなら、各実行プログラムもスレッドの上で実行されている!!)。
interrupt()
そのスレッドに割り込みをかける。割り込まれたスレッドが sleep した状態ならば、Thread.sleep クラスメソッドが InterruptedException 例外を投げて、スレッドは目覚める。ただしアプレットではこのメソッドはセキュリティマネージャのチェックに引っかかるので利用できないが、Thread.sleep クラスメソッドの呼び出しでは、常に InterruptedException 例外をキャッチするようにコーディングする必要がある。ただし、割り込み発生の時点で sleep 状態でなければ、単に割り込みは無視されるようである。なので割り込まれたかどうかが気になるのならば...
boolean isInterrupted()
で調査できる。
interruptメソッドって使いそうと思っている方々は大勢いるようですが、しかし、スレッドの処理を一旦中断されたら、再開することができない。
そこで考えてみました。スレッドを一時的に中断させるためには、すべてのクラスの親クラスObjectはwait() とnotifyAllというメソッドを用意されている。えっ、なるほどですね。まさかこれを使うわけですかね。
Thread管理においては、synchronized というキーがあります。処理しているプロセスを他のプロセスに呼び出さないようにするのはこのキーを使います。
そうすると、処理しているプロセスにタイマーを設定し、そうすると、処理しているプロセスは一時的に中断させることができるはず、また、設定されている時間になったときに、プロセスを再開することができるようになるでしょう。
例を挙げましょう。
public class TestThread implements Runnable {
private Task waitObject;
public TestThread(Task wait) {
this.waitObject=wait;
}
public void run() {
System.out.println("start");
for (int i=0; i < 100; i++) {
System.out.println(i);
if (i==10) {
try {
this.waitObject.suspend();
} catch (InterruptedException e) {
System.out.println("interrupted");
}
}
}
System.out.println("Over");
}
public static void main(String[] args) throws InterruptedException {
// 待機用のオブジェクト
Task wait=new Task();
// 待機するだけのプログラム
TestThread task=new TestThread(wait);
Thread thread=new Thread(task);
thread.start();
// 一秒待ってから
Thread.sleep(3000);
// 待機状態を解除
wait.resume();
}
}
====================
public class Task {
// このオブジェクトを使って待機状態に入る
public synchronized void suspend() throws InterruptedException {
System.out.println("stop");
this.wait();
}
// このオブジェクトを使って待機しているスレッドを全て起こす
public synchronized void resume() {
this.notifyAll();
}
}
この例を動かせば、かわりやすくなるでしょう。