2009-12-14 159 views
4

最近我需要使用RMI,並且我足夠了解我需要做的事情,但有一件事讓我感到好奇,因爲我正在重溫這個話題。是否有可能對服務器上的同一服務進行異步RMI調用?異步Java RMI

比方說,我有n個線程在客戶端和一個服務器端的對象 - 稱之爲S. S有一個方法,我想從我的客戶端線程調用,但我不希望它因爲它沒有共享資源需要擔心。

任何想法?或者這是其他方法更好的方法嗎?

+2

你有沒有真正見過,當你調用來自多個客戶端線程同樣的方法RMI堵?因爲我不知道這是規範的一部分;您應該看到與從多個線程調用本地方法相同的行爲。當然,根據計劃如何執行線程,它可能會*出現*阻塞... – kdgregory 2009-12-14 18:02:17

+0

沒有問題。要做到這一點異步,而不是阻止你的客戶端線程,你必須安排在不同的線程調用,並忽略返回。或者使用其中一種支持異步調用的「輕量級rmi替代品」。 – irreputable 2009-12-14 18:38:18

+0

我的LipeRMI fork本身支持異步RMI。 https://github.com/terraframe/lipermi – Ring 2012-06-16 22:14:22

回答

4

這樣做應該沒有問題。從服務的角度來看,它相當於多個客戶同時撥打同一服務。

任何服務器端對象都應該被寫入以保證併發訪問的安全。

+0

是的,我剛剛編碼它,它運作良好。謝謝。 – geowa4 2009-12-14 18:34:02

1

可能你應該使用類似JMS隊列的東西來處理J2EE架構上的異步調用。它在這些情況下完美運作。

1

使用Redisson框架遠程服務可以在與客戶端Redisson實例相同的節點上註冊,甚至可以在與客戶端Redisson實例共享的相同JVM上註冊。

我們假設YourServiceImpl包含您需要遠程調用的方法並實現YourService接口。

YourServiceImpl應Redisson經由RemoteService對象被註冊:

YourService yourService = new YourServiceImpl(); 

RRemoteService remoteService = redisson.getRemoteService(); 
remoteService.register(YourService.class, yourService); 

遠程調用可以以異步方式與標記 與@RRemoteAsync註釋單獨的接口進行。方法簽名應該與遠程接口中的相同方法匹配。 每種方法都應返回org.redisson.core.RFuture對象。它擴展了java.util.concurrent.Futurejava.util.concurrent.CompletionStage接口和 有幾個有用的方法。

public interface YourService { 

    Long someMethod1(Long param1, String param2); 

    void someMethod2(MyObject param); 

    MyObject someMethod3(); 

} 

// async interface for YourService 
@RRemoteAsync(YourService.class) 
public interface YourServiceAsync { 

    RFuture<Long> someMethod1(Long param1, String param2); 

    RFuture<Void> someMethod2(MyObject param); 

} 

要調用方法遠程使用YourServiceAsync接口:

RRemoteService remoteService = redisson.getRemoteService(); 
YourServiceAsync asyncService = remoteService.get(YourServiceAsync.class); 

RFuture<Long> res = asyncService.someMethod1(12L, "param"); 
res.thenApply(r -> { 
    ... 
}); 

更多文檔here