【问题标题】:what make rmi server keep running?是什么让 rmi 服务器继续运行?
【发布时间】:2011-09-16 14:13:59
【问题描述】:

我有以下 RMI 服务器代码:

public class ServerProgram {
    public ServerProgram() {
        try {
            LocateRegistry.createRegistry(1097);
            Calculator c = new CalculatorImpl();
            String name = "rmi://host:port/name";
            Naming.rebind(name, c);
            System.out.println("Service is bound......");
        } catch (Exception e) {
        }
    }
    public static void main(String[] args) {
        new ServerProgram();
    }
}

当上述程序运行时,它会一直运行以等待客户端请求。但我不明白的是,是什么让该程序不在while(true){}; 之类的地方继续运行,以及如何阻止它监听,除了停止整个程序?

【问题讨论】:

    标签: java rmi


    【解决方案1】:

    让它继续运行的是一个由 RMI 启动的-守护进程监听线程。要使其退出,请取消绑定名称并使用 UnicastRemoteObject.unexportObject() 取消导出注册表和远程对象。

    【讨论】:

    • @Muhammad 错误的答案会被否决,这就是 SO 的工作方式,并且应该解释(a)出于对作者的礼貌(b)为了他人的利益和(c)为了讨论。这称为“同行评审”。
    【解决方案2】:

    要阻止它,你应该调用

    LocateRegistry.getRegistry().unbind("rmi://host:port/name");
    

    【讨论】:

    • 错了。除非满足其他几个条件,否则解除绑定不足以阻止它。
    • @EJP 那些条件是什么?
    • 必须取消导出所有远程对象。如果没有对远程对象的远程或本地实时引用,则可以根据我的回答直接完成,也可以通过 DGC 和本地 GC 的操作来完成。
    【解决方案3】:

    但我不明白的是,是什么让该程序在不在 while(true){} 之类的情况下继续运行;以及如何阻止它收听,除了停止整个程序?

    这是由编辑 -编辑daemon thread完成的。见:What is Daemon thread in Java? 你可以用这个小例子来测试行为:

    public class DaemonThread extends Thread
    {
      public void run(){
        System.out.println("Entering run method");
        try
        {
          System.out.println(Thread.currentThread());
          while (true)
          {
            try {Thread.sleep(500);}
            catch (InterruptedException x) {}
            System.out.println("Woke up");
          }
        }
        finally { System.out.println("run finished");}
      }
    
      public static void main(String[] args) throws InterruptedException{
        System.out.println("Main");
        DaemonThread t = new DaemonThread();
        t.setDaemon(false);  // Set to true for testing
        t.start();
        Thread.sleep(2000);
        System.out.println("Finished");
      }
    }
    

    该设置阻止 JVM 关闭。在System.out.println("Finished"); 之后,您仍然可以看到线程正在运行它的"Woke up" 日志输出。

    【讨论】:

    • 不是答案。守护线程不会阻止 JVM 退出:这就是重点。根本不回答问题。
    • 非守护线程阻止 JVM 退出。见Java Language Specification
    猜你喜欢
    • 2015-06-21
    • 2015-07-04
    • 2015-02-14
    • 2013-01-11
    • 1970-01-01
    • 1970-01-01
    • 2010-10-02
    • 1970-01-01
    • 2015-04-11
    相关资源
    最近更新 更多