Java Rmi,节目还没结束?

Java Rmi,节目还没结束?,java,rmi,Java,Rmi,嗨,我有一个远程对象类,我实现了一些方法。 然后我只想在我的本地电脑上测试一下。所以我在上面添加了一个main方法。 然后在主要方面,我调用了runtUtilApp方法,它只是执行记事本,在一些睡眠之后,我完成了记事本的工作,我调用了stop方法。在所有执行之后,我等待程序完成执行。但它仍在发挥作用,而且没有结束 这是什么原因? 我想错了 }因为您的类扩展了UnicastRemoteObject,这意味着当您创建类的新实例时,将调用UnicastRemoteObject构造函数,该构造函数将此

嗨,我有一个远程对象类,我实现了一些方法。 然后我只想在我的本地电脑上测试一下。所以我在上面添加了一个main方法。 然后在主要方面,我调用了runtUtilApp方法,它只是执行记事本,在一些睡眠之后,我完成了记事本的工作,我调用了stop方法。在所有执行之后,我等待程序完成执行。但它仍在发挥作用,而且没有结束

这是什么原因? 我想错了



}

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

调用
System.exit()
退出JVM。

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

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

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

要结束线程,可以调用
System.exit()
,或者使用
UnicastRemoteObject.unexportObject(已导入的每个对象)
取消导出对象。后者的优点是不关闭JVM

这在构建可重启的服务器/网络服务时非常有用。 在这种情况下,不在旧(不再使用)对象上调用
unexportObject
,会使rmi线程混乱。此外,我假设exportedObject不会被垃圾收集删除,因为rmi线程仍在其上保留引用

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();
    }
}