• 検索結果がありません。

並行オブジェクト

ドキュメント内 JAIST Repository (ページ 45-48)

ThreadQueue

5.1 並行オブジェクト

5

MILK

のアーキテクチャ

MILKのソースコードは、トランスレータでJavaソースコードに変換して、それをJava コンパイラでコンパイルすることで実行することができる。トランスレータは、まずソー スコードをスキャナでトークンの列に切り分ける。切り分けられたトークンの列はパーサ に渡され、構文木が作成される。木の各ノードはオブジェクトで構成され、各構文の必要 な情報を保持している。そして、トランスレータはこの構文木をたどり、Javaから拡張し た構文を発見するとJavaで動作するコードに変換しながら、再び文字列に戻していく。最 後に、できた文字列をファイルに出力する。計算機言語の仕組みについては文献[23]が参 考になる。

トランスレータはJDKversion1.0.2によって実装されている。JDKSunMicrosystems

がフリーで公開しているJavaの開発キットである。トランスレータのパーサ部分はCUP

version 0.9e [24] によって実装されている。 CUPYACC に良く似た Java のための

LALR パーサのジェネレータである。

この章では MILK がどのようにして Java に変換され、Java レベルではどのように実 装されているのかを説明する。

public void sayHello(String name) {

System.out.println("Hello " + name);

}

}

5.1: 並行オブジェクトのクラス定義

5.1.1 ConcurrentObject

5.1 では親クラスを指定していない。並行オブジェクトクラスでは親クラスが指定さ れていない時には milk.runtime.ConcurrentObject が指定された事になる。また、親クラ スを指定する時には必ず ConcurrentObject を継承しているものを指定しなくてはならな い。ConcurrentObject の実装は図5.4 のようになっている。ConcurrentObject はインス タンス変数として、キューとスレッドを持っている。メソッド run() は並行オブジェクト のスレッドが最初に実行するメソッドである。このメソッドはこのクラスを継承したクラ スで実装しなくてはならない。

メソッド $MILK$activate()はスレッド生成のためのメソッドである。 メソッド

$MILK$checkQueue()はキューを調べ、キューが空の時にスレッドを破棄するためのメソッ

ドである。この2つのメソッドは同時に実行される事があってはならないのでsynchronized

宣言してある。Javaでは、同じオブジェクトのsynchronized 宣言したメソッドは同時に 実行されることはない。スレッドの扱い方には、必要な時に生成して必要が無くなった時 に破棄する方法を採用した。この他に1回だけスレッドを生成してそのスレッドを必要に 応じてサスペンドさせたりレジュームさせたりする方法が考えられる。この方法はサスペ ンドとレジュームのコストが破棄と生成のコストよりも安いように思えるが、実際はほと んど差が無い。また、サスペンドしたスレッドがあると Javaプログラムは終了しないの で、プログラムの終了条件についても考えなくてはならない。従って、前者の方法を採用 した。メソッド$MILK$checkQueue() の変数 tmp はカレントスレッドが $MILK$thread

と等しい時でも正しく動作させるために必要である。

$MILK$select() については後で説明する。$MILK$error() は並行オブジェクトで発生 したエラーを通告するためのメソッドである。

private void $MILK$sayHello(String name) {

System.out.println("Hello " + name);

}

public synchronized void sayHello(String name) {

$MILK$queue.put("A");

$MILK$queue.put(new Integer(0));

$MILK$queue.put(name);

$MILK$activate();

}

protected void $MILK$select(String name, int num) {

if (name.equals("A")) {

switch (num) {

case 0:

$MILK$sayHello((String)$MILK$queue.get());

break;

default:

$MILK$error(name, num);

break;

}

}

else {

super.$MILK$select(name, num);

}

}

5.2: Java に変換された並行オブジェクトのクラス定義

if ($MILK$thread != Thread.currentThread()) {

return;

}

while (true) {

$MILK$checkQueue();

$MILK$select((String)$MILK$queue.get(),

((Integer)$MILK$queue.get()).intValue());

}

}

}

5.2: Javaに変換された並行オブジェクトのクラス定義(つづき)

ドキュメント内 JAIST Repository (ページ 45-48)

関連したドキュメント