Rmi,节目还没结束?

时间:2012-01-19 11:26:59

标签: java rmi

您好我有一个远程对象的类,我实现了方法。 然后我只想在我当地测试它。所以我在其上添加了一个主要方法。 然后在main中,我调用了runtUtilApp方法,它只执行记事本,经过一些睡眠后我完成了记事本的工作,我调用了stop方法。全部执行后,我等待程序完成执行。但它仍然有效而不是结束。

这是什么原因? 我在想错了吗?


import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.server.*;



public class ClientImp extends UnicastRemoteObject implements Remote{

    private static final long serialVersionUID = 227L;
    private Process proc;

/**
 * constructor
 */
public ClientImp() throws RemoteException {
    super();
}


public boolean runApp() throws RemoteException {
    try {
        Runtime rt = Runtime.getRuntime();
        proc = rt.exec("notepad");
        return true;
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        return false;
    }
}


public boolean stopCurrentUtilApp() throws RemoteException {
    proc.destroy();
    return true;
}

public static void main(String[] args) {
     client;
    try {
        ClientImp client = new ClientImp();
        client.runUtilApp();
        Thread.sleep(10000);
        client.stopCurrentUtilApp();
    } catch (RemoteException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

2 个答案:

答案 0 :(得分:3)

(我知道这是一个老问题,但正如许多其他RMI相关问题引用我想完成/扩展已经给出的答案)

如前所述,JVM没有退出,因为非守护程序RMI线程仍在执行。当UnicastRemoteObject的构造函数被执行时,该线程开始执行。

此构造函数本身调用正在启动RMI线程的静态方法UnicastRemoteObject.exportObject(this, ...)

要结束线程,可以使用System.exit()调用UnicastRemoteObject.unexportObject(everyObjectThatHasBeenExported)或取消导出对象。后者的优点是不会破坏JVM。

如果您正在构建可重新启动的服务器/网络服务,这将非常有用。 在这种情况下,不在旧(不再使用)对象上调用unexportObject会使rmi线程混乱。此外,我假设exportsObject不会被垃圾收集删除,因为rmi线程仍然持有它的引用。

答案 1 :(得分:2)

因为您的类扩展了UnicastRemoteObject,这意味着当您创建类的新实例时,将调用UnicastRemoteObject构造函数,该构造函数将此对象导出为RMI服务器对象,这会导致非-daemon RMI线程启动。

调用System.exit()退出JVM。