为什么使用RMI时JVM不会终止

时间:2010-01-16 18:36:50

标签: java multithreading rmi

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

4 个答案:

答案 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,尽管这会让客户端不知道关闭。