Deep Side of Java〜Java 言語再入門 第4回 〜 アプレット、スレッド、AWT

スレッドの使い方

スレッドライブラリの使い方






スレッドの使い方

スレッドライブラリの使い方

スレッドライブラリは java.lang.Thread クラスである。Java では Thread クラスを派生させて、独自のユーザスレッドを作成する。Thread クラスでは run メソッドが空の抽象メソッドとして定義されており、これを上書きして実際の処理をさせるスレッドを作る。つまり、スレッドとして実行されるのは、run メソッドの内容である。コンストラクタなどはそのスレッド制作の準備に使うだけで、実際に走るスレッドではない。

スレッド派生クラスは作成しただけで、独自のスレッドとして走るわけではない。開始するためには start メソッドを呼び出す。だから、作成した後(コンストラクタの最後でも良い)に、start メソッドを呼び出してスレッドを走らせる必要がある。

MyThread mt = new MyThread();
mt.start();

....................

class MyThread extends Thread {
    public void run( ) {
        /* 何か、有益な処理 */
    }
}

Thread クラスのインスタンスは、個別に実際のスレッドの状態を保持している。そのため、すでに start された Thread インスタンスを多重に開始することはできないし、一旦終ったスレッドを再スタートすることもできない。複数のスレッドを起動するためには、複数のスレッドクラスのインスタンスを生成し、それぞれについて start メソッドを呼び出して起動する。

起動されたスレッドは次のような条件で停止する。

  1. run メソッドから return 文や「端から落ちて」run メソッドから抜けた。だから特に終了せずに走り続けるスレッドを書くことが多く、その場合には run メソッドの内部に無限ループがあることになる。

  2. 例外を投げて異常終了した。スレッドを起動したプロセスで、スレッドが投げた例外をキャッチする通常の方法はない。だから普通はインタプリタが例外をキャッチしてしまう。しかし、インタプリタはすべてのスレッドが終了するまで実行を継続するので、他のスレッドの実行は継続する。なのでスレッドの管理上は、スレッド内部ですべての例外は一旦キャッチして、メインプログラムでスレッド管理をするコールバックメソッドを呼び出すようにした方が無難と言うものであろう。

  3. 他のスレッドが System.exit() メソッドを実行し、インタプリタ自体が終了した。

かつて(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()
で調査できる。



copyright by K.Sugiura, 1996-2006