Newer
Older
myNWP / src / j4 / PiDistClient.java
/** 引数無しで実行すると、エラーになります。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");
	}
}