posts - 495,comments - 227,trackbacks - 0

          學習java tutorial中的rmi章節,讀書筆記


          JAVA-RMI 所采用的機制:

          1. 某Object需要remote call ,則它所有的方法都放在一個新聲明的接口中,該接口必須extends          Remote接口

             Compute接口中存放所有需要進行遠程調用的方法,讓實現該接口的類來實現這些被遠程調用的方法

          package compute;

          import java.rmi.Remote;
          import java.rmi.RemoteException;

          public interface Compute extends Remote {
              Object executeTask(Task t) throws RemoteException;
          }


          2.采用遠程調用的方法同樣有一些參數和返回值,對于這些參數和返回值,在不同JAVA虛擬機間傳輸,RM  I采取的是值傳遞,所以所有的參數和返回值必須extends Serializable

          package compute;

          import java.io.Serializable;

          public interface Task extends Serializable {
              Object execute();
          }


          /*******************************************************************************************
          上面為第一部分,在這當中,我們設計了一個接口,其中包含需要遠程調用的方法,然后讓該接口的實現者(即遠程對象的owner)來實現這些方法
          *******************************************************************************************/


          3. 現在我們為了得到遠程對象,就來實現一下上面定義的接口:
             main函數中,新建一個遠程對象engine,并將它與名字name邦定:Naming.rebind(name, engine);

          注:The superclass UnicastRemoteObject supplies implementations for a number of     java.lang.Object methods (equals, hashCode, toString) so that they are defined     appropriately for remote objects. UnicastRemoteObjectalso includes constructors and     static methods used to export a remote object, that is, make the remote object available     to receive incoming calls from clients.

          package engine;

          import java.rmi.*;
          import java.rmi.server.*;
          import compute.*;

          public class ComputeEngine extends UnicastRemoteObject
                                     implements Compute
          {
              public ComputeEngine() throws RemoteException {
                  super();
              }

              public Object executeTask(Task t) {
                  return t.execute();
              }

              public static void main(String[] args) {
                  if (System.getSecurityManager() == null) {
                      System.setSecurityManager(new RMISecurityManager());
                  }
                  String name = "http://host/Compute";
                  try {
                      Compute engine = new ComputeEngine();
                      Naming.rebind(name, engine);
                      System.out.println("ComputeEngine bound");
                  } catch (Exception e) {
                      System.err.println("ComputeEngine exception: " +
                    e.getMessage());
                      e.printStackTrace();
                  }
              }
          }

          /*******************************************************************************************
          上面為第二部分,在這當中,我們得到了一個實現了Compute接口的遠程對象engine,注意:engine中只有那些Compute接口中的方法能夠被遠程調用,其他方法只能本地調用。現在,將遠程對象engine邦定到RMI Registry 。 client可以從registry那里得到engine的引用,實際上是一個stub,相當于一個engine的代理,遠程方法被client調用以后,可以改變engine的狀態
          *******************************************************************************************/
            
          4. 下面我們實現那些遠程方法調用時所要用到的參數:Task

          package client;

          import compute.*;
          import java.math.*;

          public class Pi implements Task {

              /** constants used in pi computation */
              private static final BigDecimal ZERO =
                  BigDecimal.valueOf(0);
              private static final BigDecimal  ONE =
                  BigDecimal.valueOf(1);
              private static final BigDecimal FOUR =
                  BigDecimal.valueOf(4);

              /** rounding mode to use during pi computation */
              private static final int roundingMode =
                  BigDecimal.ROUND_HALF_EVEN;

              /** digits of precision after the decimal point */
              private int digits;
             
              /**
               * Construct a task to calculate pi to the specified
               * precision.
               */
              public Pi(int digits) {
                  this.digits = digits;
              }

              /**
               * Calculate pi.
               */
              public Object execute() {
                  return computePi(digits);
              }

              /**
               * Compute the value of pi to the specified number of
               * digits after the decimal point.  The value is
               * computed using Machin's formula:
               *
               *          pi/4 = 4*arctan(1/5) - arctan(1/239)
               *
               * and a power series expansion of arctan(x) to
               * sufficient precision.
               */
              public static BigDecimal computePi(int digits) {
                  int scale = digits + 5;
                  BigDecimal arctan1_5 = arctan(5, scale);
                  BigDecimal arctan1_239 = arctan(239, scale);
                  BigDecimal pi = arctan1_5.multiply(FOUR).subtract(
                                            arctan1_239).multiply(FOUR);
                  return pi.setScale(digits,
                                     BigDecimal.ROUND_HALF_UP);
              }
              /**
               * Compute the value, in radians, of the arctangent of
               * the inverse of the supplied integer to the speficied
               * number of digits after the decimal point.  The value
               * is computed using the power series expansion for the
               * arc tangent:
               *
               * arctan(x) = x - (x^3)/3 + (x^5)/5 - (x^7)/7 +
               *     (x^9)/9 ...
               */  
              public static BigDecimal arctan(int inverseX,
                                            int scale)
              {
                  BigDecimal result, numer, term;
                  BigDecimal invX = BigDecimal.valueOf(inverseX);
                  BigDecimal invX2 =
                      BigDecimal.valueOf(inverseX * inverseX);

                  numer = ONE.divide(invX, scale, roundingMode);

                  result = numer;
                  int i = 1;
                  do {
                      numer =
                          numer.divide(invX2, scale, roundingMode);
                      int denom = 2 * i + 1;
                      term =
                          numer.divide(BigDecimal.valueOf(denom),
                                       scale, roundingMode);
                      if ((i % 2) != 0) {
                          result = result.subtract(term);
                      } else {
                          result = result.add(term);
                      }
                      i++;
                  } while (term.compareTo(ZERO) != 0);
                  return result;
              }
          }

          5. 最后我們實現client對象
             遠程對象comp是通過RMI的注冊表來查找到的

          package client;

          import java.rmi.*;
          import java.math.*;
          import compute.*;

          public class ComputePi {
              public static void main(String args[]) {
                  if (System.getSecurityManager() == null) {
                      System.setSecurityManager(new RMISecurityManager());
                  }
                  try {
                      String name = "http://" + args[0] + "/Compute";
                      Compute comp = (Compute) Naming.lookup(name);
                      Pi task = new Pi(Integer.parseInt(args[1]));
                      BigDecimal pi = (BigDecimal) (comp.executeTask(task));
                      System.out.println(pi);
                  } catch (Exception e) {
                      System.err.println("ComputePi exception: " +
                                         e.getMessage());
                      e.printStackTrace();
                  }
              }
          }

          posted on 2008-04-03 13:25 SIMONE 閱讀(988) 評論(1)  編輯  收藏 所屬分類: rmi

          FeedBack:
          # re: JAVA-RMI學習心得
          2008-05-13 11:21 | 狀元郎
          ICE是個很有潛力的中間件架構。語言中立。性能很好。
          據說是用來替代CORBA和RMI的。  回復  更多評論
            

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 无棣县| 陇川县| 岐山县| 慈利县| 平和县| 额济纳旗| 宜兰县| 呼玛县| 绵阳市| 吴忠市| 凉城县| 饶阳县| 连云港市| 桐柏县| 南丹县| 治县。| 日照市| 句容市| 乌拉特中旗| 新邵县| 普格县| 梁山县| 农安县| 德钦县| 徐汇区| 达拉特旗| 阜康市| 广州市| 伊宁县| 绥棱县| 重庆市| 肇州县| 会同县| 西青区| 铅山县| 宁强县| 保定市| 敖汉旗| 木兰县| 宜丰县| 资溪县|