1) Если я реализую свой пульт RMI
методы как синхронизированы, они
гарантированно будет взаимоисключающим? я
нужно убедиться, что нет двух моих
Методы RMI (методы, предлагаемые для
клиенты) выполняют одновременно.
RMI не предоставляет такой гарантии самостоятельно (в отличие от EJB), и два вызова одного и того же удаленного объекта могут выполняться одновременно, если вы не реализуете некоторую синхронизацию. Ваш подход верен, и синхронизация всех методов действительно гарантирует, что никакие два из них не будут работать одновременно на одном и том же объекте. Примечание. Одно ключевое слово synchronized
эквивалентно synchronized( this )
.
.
2) У меня есть метод, который сервер
выполняется периодически. Используется для
делать уборки. Я должен убедиться, что
этот конкретный метод не
выполнить, когда есть какой-либо метод RMI
выполняется / используется удаленными клиентами.
Если задание очистки относится к другому классу, вам необходимо определить блокировку, которую вы будете использовать для удаленного объекта и задания очистки. В удаленном объекте определите переменную экземпляра, которую вы будете использовать в качестве блокировки.
protected Object lock = new Object();
По соглашению, люди используют Object
для этой цели. Затем вам нужно захватить блокировку вашей периодической работы с помощью synchronized( remoteObj.lock ) { ... }
, предполагая, что она находится в том же пакете.
Другие методы в удаленном объекте необходимо будет синхронизировать одинаково (одного synchronized
недостаточно), так что удаленные вызовы методов и периодическое задание являются исключительными.
Я рассмотрел реализацию RMI
методы как статические и в том числе
метод очистки внутри RMI
интерфейс, но, похоже, не
элегантный способ решения проблемы.
Я также написал метод очистки
внутри интерфейса RMI как
синхронизированы. Когда я побежал за
тестирование, похоже, не было
столкновения между методами, но я
не могу быть уверен.
Если я хорошо понимаю, вы хотели бы, чтобы логика очистки была статическим методом? Статический метод только с synchronized
захватывает блокировку класса. «Обычный» метод с synchronized
захватывает блокировку экземпляра объекта. Это не те же самые скрытые блокировки!
Но если у вас есть только один экземпляр удаленного объекта, вы можете сделать lock статическим (Это то же самое, что блокировка класса, но немного чище). Код очистки может быть статичным и находиться в том же классе, что и удаленный объект.
Скелет:
public class MyRemoteClass {
public static Object lock = new Object();
public void doStuff()
{
synchronized( lock ) { ... }
}
}
public class Cleanup {
public static void doIt()
{
synchronized( MyRemoteClass.lock ) { ... }
}
}