我刚从http://java.sun.com/docs/books/tutorial/rmi/implementing.html
的太阳看了RMI上的小道当我运行该示例时,尽管main已完成,但JVM不会终止。 RMI是否在内部产生线程?
在主要退出后,main中生成的多个线程的行为是什么? 它是一种干净的方式让线程随时退出,或者你应该在你生成的每个线程上进行连接?我没有找到关于这个问题的任何文件。
非常感谢你的帮助!!
public class ComputeEngine implements Compute {
public ComputeEngine() {
super();
}
public <T> T executeTask(Task<T> t) {
return t.execute();
}
public static void main(String[] args) {
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
try {
String name = "Compute";
Compute engine = new ComputeEngine();
Compute stub = (Compute) UnicastRemoteObject.exportObject(engine, 0);
Registry registry = LocateRegistry.getRegistry();
registry.rebind(name, stub);
System.out.println("ComputeEngine bound");
} catch (Exception e) {
System.err.println("ComputeEngine exception:");
e.printStackTrace();
}
}
}
答案 0 :(得分:6)
创建一个线程来监听套接字并回复对象的请求。停止JVM的一种方法是取消绑定服务器:
Registry.unbind()
并取消导出对象:
UnicastRemoteObject.unexportObject()).
答案 1 :(得分:2)
您可以使用JDK中包含的jstack实用程序来查看在java程序中运行的线程,甚至是这些线程所在的行。
因此,如果您的程序仍在运行,您只需在pid上运行jstack,它将告诉您哪些线程仍在运行以及它们正在执行的操作。
答案 2 :(得分:2)
关于“多线程的行为”问题的一部分:是的,JVM将继续运行直到所有线程都完成。唯一的例外是标记为守护进程的线程(请参阅Thread.setDaemon()),JVM不会等待它们。
答案 3 :(得分:1)
是的,当您通过RMI公开对象时,它需要一个线程来接受对这些对象的传入请求。这个线程可能是一个守护程序线程,它不会阻止JVM退出,但它不是出于几个原因,只要仍有活动的导出对象,它就会阻碍JVM正常退出。因此,您可以对所有对象使用unexportObject,或者只使用System.exit()来结束JVM,尽管这会让客户端不知道关闭。