2012-01-19 56 views
1

嗨我有一個類是一個遠程對象,我實現了方法。 然後我只是想在我的本地測試它。所以我添加了一個主要方法。 然後在main中,我調用了runtUtilApp方法,它只是執行記事本,經過一些睡眠之後我完成了記事本的工作,並且我稱之爲停止方法。完成執行後,我等待程序完成執行。但它仍在工作,並沒有結束。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(); 
    } 
} 

}

回答

2

因爲你的類繼承了UnicastRemoteObject,這意味着當你創建類的新實例,該UnicastRemoteObject構造函數被調用,其中出口這個對象作爲RMI服務器對象,這會導致非守護進程的RMI線程啓動。

請致電System.exit()退出JVM。

2

(我知道這是一個老問題,但因爲它是由許多其他RMI相關的問題,我想完成引用/延長一個已經給出了答案)

如前所述,在JVM沒有退出因爲非守護進程的RMI線程仍在執行。此線程在UnicastRemoteObject的構造函數執行時開始執行。

該構造函數本身調用啓動RMI線程的靜態方法UnicastRemoteObject.exportObject(this, ...)

要結束線程,可以調用System.exit()或使用UnicastRemoteObject.unexportObject(everyObjectThatHasBeenExported)導出對象。後者的優點是不會阻止JVM。

如果您正在構建可重新啓動的服務器/網絡服務,這是有用的。 在這種情況下,不會在舊的(不再使用的)對象上調用unexportObject混亂rmi線程。此外,我假設exportedObject不會被垃圾收集刪除,因爲rmi線程仍然在其上持有引用。