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