スレッドの制御 |
ここで示される Clock アプレット:
現在の時刻を表示して、秒ごとにそのディスプレイを更新する。 時計が更新し続ける間、このページをスクロールして他のタスクを実行することができる。時計のディスプレイを更新するコードがそれ自身のスレッド内で実行するからである。
このページでは、Clock アプレットの ソースコード を強調表示して、詳細に説明する。 特にこのページでは、時計のスレッド対応のふるまいを実装するコードセグメントについて説明する。アプレットのライフサイクルと関連したコードセグメントは説明しない。 もし前にユーザ自身のアプレットを作成したことがないか、あるいはアプレットのライフサイクルに精通していないなら、このページを進む前に、アプレットのライフサイクルを一読したほうがよい。
Runnable インタフェース使用の決定
Clock アプレットはそのスレッドのrun()
メソッドを提供するために、Runnable インタフェースを使用する。 Java 互換のブラウザ内で実行するために、Clock クラスは Applet クラスから派生しなければならない。 しかし、その中で実行しているプロセスを引き継がずに、連続的にそのディスプレイを更新することができるように、Clock アプレットもスレッドを使用する必要がある。 しかし Java 言語は多重継承をサポートしないので、Clock クラスは、アプレットからと同様に Thread から継承することができない。 したがって、Clock クラスはそのスレッド対応の動作を提供するために、Runnable インタフェースを使用する。アプレットはスレッドではない。同様に Java 互換のブラウザあるいは Applet ビューワーは、自動的にアプレットを実行するスレッドを作成しない。 したがって、もしアプレットが任意のスレッドを必要とするなら、アプレットはそれ自身のスレッドを作成しなくてはならない。 クロックアプレットは、頻繁にディスプレイを更新し、また時計が動いているのと同時に、ユーザが他のタスク(別のページに進んだり、ページをスクロールするなど)を実行できる必要があるので、そのディスプレイ更新を実行するスレッドを必要とする。
Runnable インタフェース
クロックアプレットは、Runnable インタフェースによってスレッドのrun()
メソッドを提供する。 Clock クラスのクラス定義は、Clock がアプレットのサブクラスであって、 Runnable インタフェースを実装することを表す。 インタフェースに精通していなければ、オブジェクト、クラス、インタフェースで復習すること。Runnable インタフェースは、引数を受け入れず、値を返さないclass Clock extends Applet implements Runnable {run()
と呼ばれるひとつのメソッドを定義する。 Clock クラスが Runnable インタフェースを実装するので、インタフェースで定義されたようにrun()
メソッドのための実装を提供しなくてはならない。 しかし、Clock のrun()
メソッドを説明する前に、他の Clock コードの要素を見る必要がある。スレッドの作成
アプレットが実行しているアプリケーションは、アプレットをロードする時に、アプレットのstart()
メソッドを呼び出す。 Clock アプレットは、start()
メソッド でclockThread
と指定されたThreadを作成して、スレッドを開始する。最初に、public void start() { if (clockThread == null) { clockThread = new Thread(this, "Clock"); clockThread.start(); } }start()
メソッド は、clockThread
が null であるかどうかを調べる。clockThread
が null の場合、アプレットは真新しいか、あるいは前に停止されて、新規のスレッドが作成されている。 そうでなければ、アプレットはすでに実行している。 アプレットは次の実行で新規のスレッドを作成する。clockThread = new Thread(this, "Clock");this
− Clock アプレット − がスレッドコンストラクタに最初の引数として渡されるので、注意すること。 Thread コンストラクタへの最初の引数は、Runnable インタフェースを実装しなくてはならなず、スレッドのターゲットになる。 このようにして作成されると、clockThread
のスレッドは、そのターゲットの Runnable オブジェクト(この場合Clock アプレット)からそのrun()
メソッドを得る。2 番目の引数はスレッドの名前である。
スレッドの停止
Clock アプレットを表示するページを出る時、アプレットが実行しているアプリケーションは、アプレットのstart()
メソッドを呼び出す。 Clock のstop() メソッド
は、スレッドを停止して null にセットする。 これにより、時計の連続更新を停止する。ページを再び訪れた場合、public void stop() { clockThread.stop(); clockThread = null; }start()
メソッドは再度呼び出され、時計は新規のスレッドで再開始する。run メソッド
最後に、Clock のrun()
メソッドはClock アプレットの中心部を実装して、次のようになる。以前の節で見たように、アプレットを停止するように要求すると、アプレットはpublic void run() { while (clockThread != null) { repaint(); try { clockThread.sleep(1000); } catch (InterruptedException e){ } } }clockThread
を停止して、それを null にセットする。これにより、run()
メソッドに停止する時期を知らせる。 したがってrun()
メソッドの最初の行は、clockThread
が停止されるまでループする。 ループ内で、アプレットはそれ自身をリペイントし、Thread に1秒( 1000 ミリ秒)間スリープすることを知らせる。 アプレットのrepaint()
メソッドは、最後にはアプレットの表示領域の実際の更新を行うアプレットのpaint()
メソッドを呼び出す。 Clock アプレットのpaint()
メソッドは現在の時刻を得て、画面にそれを描く。public void paint(Graphics g) { Date now = new Date(); g.drawString(now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds(), 5, 10); }
スレッドの制御 |