/** 引数無しで実行すると、エラーになります。Execボタンは使用できません。 */
package j4;
// RMIによる分散処理プログラムの実装例
// (5)クライアントプロセス実装のクラスファイル
// PiDistClient.java
// このクラスは、クライアントプロセスのクラスです
// 分散処理システムにおけるクライアントの機能を記述します
// RMIレジストリにおける名前の取得や、サーバへの仕事の依頼を行います
// 使用方法
// java j4.PiDistClient サーバ名1 サーバ名2 ・・・
// なお、クライアント起動の前に、サーバとレジストリを起動してください
// ライブラリの利用
import java.rmi.Naming;
//PiDistClientクラス
public class PiDistClient {
// mainメソッド
public static void main(String args[]) {
// long result = 0 ;//サーバの計算結果を格納する
long millis;// 経過時間
long maxloopcount = 10000000;// 点の個数
int i;// サーバの数
// スレッドを構成するための配列を宣言する
// PiDistClientでは、サーバの数だけスレッドを作成します
// 各スレッドはサーバの計算処理終了を待ち、
// 終了後Resultクラスのオブジェクトに結果を報告します
LaunchPiServer l[] = new LaunchPiServer[args.length];
Thread t[] = new Thread[args.length];
// 処理の本体
try {
// 処理時間計測開始
millis = System.currentTimeMillis();
// 引数で指定されたサーバに処理を依頼します
for (i = 0; i < args.length; i++) {
// 引数の個数だけ処理を繰り返します
// 各サーバごとにスレッドを割り当てる
l[i] = new LaunchPiServer(args[i],
maxloopcount / args.length, millis);
t[i] = new Thread(l[i]);
t[i].start();// 処理の開始
}
} catch (Exception e) {
System.out.println(e);
}
}
}
// LaunchPiServerクラス
// サーバに対して処理を依頼し、結果を受け取ります
// サーバから受け取った処理結果は、
// Resultクラスのcollect()メソッドで集計します
class LaunchPiServer implements Runnable {
String address;// サーバのアドレスを格納する
long maxl;// 繰り返しの回数(点の数)
long millis;// 処理開始時刻を格納する
// コンストラクタ
public LaunchPiServer(String name, long maxloopcount, long m) {
// 呼び出し側から受け取った値をクラス内部で保持します
address = name;
maxl = maxloopcount;
millis = m;
}
// スレッドの本体
public void run() {
Pi p;// サーバ用オブジェクト
try {
// PiServiceの利用
p = (Pi) Naming.lookup("//" + address + "/PiService");
// サーバが見つかったので、処理を依頼します
System.out.println("Start " + address);
Result.collect(address, maxl, millis, p.putPi(maxl));
} catch (Exception e) {
System.out.println(e);
}
}
}
// Resultクラス
// 各サーバから返された値を集計します
class Result {
static int i = 0;
static long all = 0;
// collectメソッド
// 複数のスレッドから呼び出されるため、排他制御が必要になります
// このため、synchronizedというキーワードを付けて
// メソッドを宣言します
// 引数の一覧
// address サーバのアドレス
// maxloopcount サーバが生成した点の個数
// misllis 処理開始時刻
// res 円の内側に入った点の個数
// collect()メソッド
static public synchronized void collect(String address, long maxloopcount, long millis,
long res) {
System.out.println("Finish " + address);
// 円周率πの近似値の計算
all += res;// これまでの結果に、新たに得られた結果を加算
++i;// 返事を返したサーバの個数を数えます
// πの近似値を出力します
System.out.println(" " +
(double) all / (maxloopcount * i) * 4);
// 経過時間を出力します
millis = System.currentTimeMillis() - millis;
System.out.println(" " + (double) millis / 1000 + "sec");
}
}