Previous | Next | Trail Map | Writing Java Programs | スレッドの制御


クロックアプレット

ここで示される Clock アプレット:


ブラウザはアプレットタグを理解しない。 理解していれば、ここでクロックアプレットのスクリーンショットが見られるだろう。


現在の時刻を表示して、秒ごとにそのディスプレイを更新する。 時計が更新し続ける間、このページをスクロールして他のタスクを実行することができる。時計のディスプレイを更新するコードがそれ自身のスレッド内で実行するからである。

このページでは、Clock アプレットの ソースコード を強調表示して、詳細に説明する。 特にこのページでは、時計のスレッド対応のふるまいを実装するコードセグメントについて説明する。アプレットのライフサイクルと関連したコードセグメントは説明しない。 もし前にユーザ自身のアプレットを作成したことがないか、あるいはアプレットのライフサイクルに精通していないなら、このページを進む前に、アプレットのライフサイクル(in the Writing Applets trail)を一読したほうがよい。

Runnable インタフェース使用の決定

Clock アプレットはそのスレッドの run() メソッドを提供するために、Runnable インタフェースを使用する。 Java 互換のブラウザ内で実行するために、Clock クラスは Applet クラスから派生しなければならない。 しかし、その中で実行しているプロセスを引き継がずに、連続的にそのディスプレイを更新することができるように、Clock アプレットもスレッドを使用する必要がある。 しかし Java 言語は多重継承をサポートしないので、Clock クラスは、アプレットからと同様に Thread から継承することができない。 したがって、Clock クラスはそのスレッド対応の動作を提供するために、Runnable インタフェースを使用する。

アプレットはスレッドではない。同様に Java 互換のブラウザあるいは Applet ビューワーは、自動的にアプレットを実行するスレッドを作成しない。 したがって、もしアプレットが任意のスレッドを必要とするなら、アプレットはそれ自身のスレッドを作成しなくてはならない。 クロックアプレットは、頻繁にディスプレイを更新し、また時計が動いているのと同時に、ユーザが他のタスク(別のページに進んだり、ページをスクロールするなど)を実行できる必要があるので、そのディスプレイ更新を実行するスレッドを必要とする。

Runnable インタフェース

クロックアプレットは、Runnable インタフェースによってスレッドの run() メソッドを提供する。 Clock クラスのクラス定義は、Clock がアプレットのサブクラスであって、 Runnable インタフェースを実装することを表す。 インタフェースに精通していなければ、オブジェクト、クラス、インタフェース(in the Writing Java Programs trail)で復習すること。

class Clock extends Applet implements Runnable {

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);
}


Previous | Next | Trail Map | Writing Java Programs | スレッドの制御