2009-12-14 111 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