2009-12-14 4 views
4

Недавно мне нужно было использовать RMI, и я достаточно знаю, что мне нужно делать, но меня удивляет одна вещь, когда я пересматриваю эту тему. Возможно ли сделать асинхронные вызовы RMI той же службе на сервере?Асинхронный Java RMI

Предположим, у меня есть n потоков на клиенте и один объект на стороне сервера - назовите его S. S имеет единственный метод, который я хочу вызвать из своих потоков на стороне клиента, но я не хочу его блокировать, поскольку у него нет общего ресурса, о котором можно беспокоиться.

Любые идеи? Или это то, что лучше всего оставить другим методам?

+2

ли вы на самом деле видели RMI блокировки при вызове тот же метод из нескольких клиентских потоков? Потому что я не знаю, что это часть спецификации; вы должны увидеть такое же поведение, как вызов локального метода из нескольких потоков. Конечно, в зависимости от того, как расписание выполняет потоки, оно может * появляться * блокировать ... – kdgregory

+0

проблем нет. чтобы сделать это асинхронно, а не блокировать поток клиентов, вам нужно организовать вызов в другом потоке и проигнорировать возврат. Или используйте одну из этих «альтернатив» с малым весом, которая поддерживает асинхронный вызов изначально. – irreputable

+0

My LipeRMI fork поддерживает асинхронный RMI. https://github.com/terraframe/lipermi – Ring

ответ

4

Не должно быть никаких проблем с этим. Это эквивалентно тому, что несколько клиентов одновременно называют одну услугу с точки зрения сервиса.

Любой объект на стороне сервера должен быть написан для обеспечения безопасности при одновременном доступе.

+0

Да, я просто закодировал его, и он работал хорошо. Благодарю. – geowa4

1

Возможно, вы должны работать с чем-то вроде JMS-очереди для асинхронных вызовов в архитектуре J2EE. В этих случаях он отлично работает.

1

Использование Redisson рамочная удаленная служба может быть зарегистрирована на том же узле с клиентской стороной экземпляра Redisson и даже на том же JVM, совместно используемом экземпляром Redisson на стороне клиента.

Предположим, что 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.Future и java.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