Newer
Older
myNWP.git / src / j4 / PiDistClient.java
@Motoki Miura Motoki Miura on 2 Oct 2020 4 KB vars
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") ;
	}
}