您好我有一个远程对象的类,我实现了方法。 然后我只想在我当地测试它。所以我在其上添加了一个主要方法。 然后在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();
}
}
}
答案 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。