JAVA RMI 文檔中文(三)

2.7 遠端對象的定位

一個簡單的命名服務器可以存儲命名的遠端對象的引用。java.rmi.Naming可以使用以URL爲基礎的方法存儲一個遠端對象的引用。

對於客戶端來說,如果要調用遠端對象的方法的話,那麼需要先獲取到遠端對象的引用。一個遠端引用通常可以作爲方法調用的參數或者返回值來獲取。RMI系統提供了簡單的命名服務器,它用於從指定的主機上獲取遠端對象。java.rmi.Naming提供了一系列基於URL的方法(look up, bind, rebind, unbind, list),這些方法用於操作指定主機和端口下維護的 對象-名稱 對。

3.1 存根和骨架Stubs and Skeletons
(後面這兩個詞還是直接用英文吧)

RMI使用了標準的遠程通信機制:stubs and skeletons。stub相當於遠端對象在客戶端的代理。當用戶調用本地的stub上的方法,stub就要負責執行遠端對象的該方法。對應於遠端對象的stub需要實現遠端對象實現的所有接口。

當一個stub中的方法被調用時,stub會做下面的事:

1、與擁有遠端對象的遠端虛擬機創建連接。
2、發送參數到遠端虛擬機。
3、等待返回結果。
4、獲取返回結果或者異常信息
5、將返回結果返回給用戶。

stub隱藏了參數序列化和網絡級的通信細節,這樣是爲了讓用戶可以方便使用。

在遠端虛擬機中,每一個遠端對象可能會有一個相對應的skeleton(在 java2 平臺環境下(java 2 platform-only),skeleton不是必須的)。skeleton負責分發調用到真正的遠端對象實現。當一個skeleton接收到一個方法請求時,skeleton會做如下事:

1、獲取遠端方法的參數。
2、調用實際遠端方法實現。
3、傳遞結果給調用者。

java1.2中增加了額外的stub協議,該協議消除了Java 2平臺環境中對框架的需求。在JDK1.1中卻相反,通常都是使用skeleton來實現任務。Stub和Skeleton通過rmic編譯器生成。

3.2 在遠端方法調用中線程的使用

在RMI運行時,方法分配到遠端實現可能在一個線程中或者不在一個線程。RMI運行時不能保證遠端對象和線程的映射關係。因爲同一個遠端對象的遠端方法可能會同時執行,所以一個遠端對象在實現時需要確保線程安全。

3.3 遠端對象的垃圾回收機制

和在本地系統一樣,在分佈式系統中,我們也希望遠端對象可以自動刪除,可以不再被客戶端引用。遠端對象可以在合適的時候自動刪除,這樣的話,程序員就可以不用跟蹤遠端對象了。RMI使用了引用計數垃圾回收算法,它與Modula-3`s Network Objects有些相似。

爲了實現引用計數的垃圾回收算法,RMI在運行時會跟蹤所有每個虛擬機中存活的引用。當一個活的引用進入虛擬機時,它的(這裏指的是該引用)引用計數就增加。一個對象的第一個引用會發送“已引用”的信息到服務端The first reference to an object sends a “referenced” message to the server for the object。在本地虛擬機中當引用變爲未被引用時,引用計數就會減少。當最後一個引用死掉的時候,會發送一個未被引用的信息給服務端。當然協議中還有很多細節。所有這些協議都是通過維持引用的順序和未被引用消息來保證對象不會被過早的回收。

當一個遠端對象沒有被任何客戶端引用,RMI在運行時會將其視爲弱引用。弱引用允許虛擬機的垃圾回收器在沒有其他本地對象引用它的情況下,丟棄該對象。分佈式垃圾回收算法和本地虛擬機的垃圾回收器通過維護對象正常的引用或者弱引用來相互作用。

只要本地存在對遠端對象的引用,那麼該對象就不能被回收,而且它可以在方法調用中被傳遞。通過傳遞遠程對象將虛擬機的標識傳到引用的集合中。一個遠端對象必須實現java.rmi.server.Unreferenced接口纔會有取消引用通知。當引用不存在的時候,unreferenced方法就會被調用。unreferenced方法在引用集爲空的時候被調用,所以該方法可能會被調用多次。遠端對象只有在本地或者遠端的引用不存在的時候纔會被回收。

注意,如果在服務端和客戶端之間存在網絡分區,那麼可能會出現過早回收遠端對象的情況(因爲在傳輸過程中可能會認爲客戶端已經崩潰了)。由於這種可能,遠端引用不能保證引用的完整性;換句話說,一個遠端引用可能會指向一個不存在的對象。一旦出現這種情況,就會拋出RemoteException異常,該異常必須有應用來處理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章