1. 程式人生 > >JAVA RMI 文件中文(三)

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異常,該異常必須有應用來處理。