关于RMI的程序结果

时间:2012-03-24 14:04:45

标签: java rmi

我有两个问题

结果将如下所示。

  

1 1 1 1 1

     

1 1 1 1 1

     

1 1 1 1 1

     

1 2 3 5 8

     

1 2 3 5 8

  1. 为什么前三个结果相同?
  2. 为什么第四个可以使用远程实现对象。
  3. 以下是代码:

    FibClient.java

    package fib;
    import java.rmi.Naming;
    import java.io.*;
    
    public class FibClient {
    
        public static void main(String args[]) {
            try {
                int numFibNum;
                String registryURL = "rmi://localhost:1099/fib";
                FibInterface h1 = (FibInterface)Naming.lookup(registryURL);
                numFibNum = 5;
                Fib c = new Fib();
                //numFibNum = Integer.parseInt(args[0]);
                for (int i=0; i<numFibNum; i++) {
                    h1.getNextFibNum(c);
                    System.out.print(h1.getNextFibNum(new Fib())+" ");
                }
                System.out.println();
    
                for (int i=0; i<numFibNum; i++) {
                    System.out.print(h1.getNextFibNum(h1.getFib(0,1))+" ");
                }
                System.out.println();
    
                Fib f = new Fib();
                for (int i=0; i<numFibNum; i++) {
                    System.out.print(h1.getNextFibNum(f)+" ");
                }
                System.out.println();
    
                FibImpl h2 = new FibImpl();
                for (int i=0; i<numFibNum; i++) {               
                    System.out.print(h2.getNextFibNum(f)+" "); 
                }
                System.out.println();
    
                f = new Fib();
                for (int i=0; i<numFibNum; i++) {               
                    f = h1.getNextFib(f);
                    System.out.print(f.getF1()+" ");                
    
                }
    
                System.out.println();   
            } catch(Exception ex) {
                ex.printStackTrace();
            }
        }
    
    }
    

    FibImpl.java

    package fib;
    import java.rmi.RemoteException;
    import java.rmi.server.UnicastRemoteObject;
    @SuppressWarnings("serial")
    public class FibImpl extends UnicastRemoteObject implements FibInterface {
    public FibImpl() throws RemoteException {
        super();
    }
    public Fib getFib(int f0, int f1) throws RemoteException {
        return new Fib(f0, f1);
    }
    public int getNextFibNum(Fib f) throws RemoteException {
        sleep(500);
        int nextFib = f.getF0() + f.getF1();
        f.setF0(f.getF1());
        f.setF1(nextFib);
        return nextFib;
    }
    public Fib getNextFib(Fib f) throws RemoteException {
        sleep(500);
        int nextFib = f.getF0() + f.getF1();
        f.setF0(f.getF1());
        f.setF1(nextFib);
        return f;
    }
    private void sleep(int time) {
        try {
            Thread.sleep(time);
        }
        catch(InterruptedException ex) {
            ex.printStackTrace();
        }
    }
    }
    

    Fib.java

    package fib;
    import java.io.Serializable;
    @SuppressWarnings("serial")
    public class Fib implements Serializable {
    private int f0;
    private int f1;
    public Fib() {
        this(0,1);
    }
    public Fib(int f0, int f1) {
        this.f0 = f0;
        this.f1 = f1;
    }   
    public int getF0() {
        return f0;
    }
    public void setF0(int f0) {
        this.f0 = f0;
    }
    public int getF1() {
        return f1;
    }
    public void setF1(int f1) {
        this.f1 = f1;
    }   
    }
    

1 个答案:

答案 0 :(得分:1)

回答第一个问题:在第一个案例中,你是在每次远程调用时创建一个新的Fib对象,所以你总是从0 + 1开始。在第三种情况下,即使在客户端您正在维护相同的对象,对RMI的更改是不可见的。

您无法通过RMI调用更改对象的内容,因为对象不同。当您调用RMI方法时,对象在另一侧被序列化和反序列化,因此实际存在该对象的两个副本。更改服务器端的副本对客户端没有影响。

在第四种情况下,您使用本地对象来计算Fibonacci数,因此当传递给方法的对象发生更改时,新内容在调用代码中可见。