Java RMI и вопросы о Синхронизации Потока

Я на самом деле имею два вопроса о Java RMI и распараллеливаю синхронизацию:

1) Если я реализую свои удаленные методы RMI, как синхронизируется, то они, как гарантируют, будут взаимоисключающими? Я должен удостовериться, что никакие два из моих методов RMI (методы, предлагаемые клиентам), не выполняются одновременно.

2) У меня есть метод, который сервер периодически выполняет. Это используется, чтобы сделать очистки. Я должен удостовериться, что этот конкретный метод не выполняется, когда существует любое RMI метод быть, выполняют/используют удаленными клиентами. Кроме того, когда тот метод работает, вызовы RMI не должны быть возможными. Т.е. Клиенты должны ожидать. Какая-либо идея, как я могу сделать это? Я читал о Блокировках, но я не знаю, как использовать их в этом сценарии.

Я считал реализацию методами RMI как статичную и включая тот метод очистки в интерфейсе RMI, но это, кажется, не изящный способ решить проблему.

Я также записал метод очистки в интерфейсе RMI, как синхронизируется. Когда я выполнил его для тестирования, между методами, казалось, не было коллизий, но я не могу быть уверен.

Спасибо за Ваше время и ответы.

5
задан Inf.S 16 February 2010 в 19:55
поделиться

2 ответа

  1. Для каждого вызова от клиента RMI сервер RMI будет выполнять вызов в новом потоке. Вам нужно только синхронизировать доступ к общим объектам.

  2. Другой поток или таймер не помешают вашему серверу принимать вызовы со стороны клиента. Для этого требуется синхронизация. Лучшая практика зависит от того, как долго выполняется задание очистки, можно ли его прервать, можно ли поместить запросы в очередь и т. Д. Самый простой способ - позволить методам RMI ждать для замка, как уже было описано ewernli.

РЕДАКТИРОВАТЬ: Согласно вашему комментарию, скелет, демонстрирующий, как достичь такого рода базовой синхронизации. Поскольку теперь все взаимоисключающе, вы не можете ожидать высокой производительности с несколькими задействованными клиентами. В любом случае это покроет ваши требования. (Я надеюсь). Если ваш проект растет, вам следует прочитать Учебное пособие по параллелизму

Object mutex = new Object();

int rmiMethod1() {
    synchronized (mutex) {
        doWhatNeeded1();
    }
}

int rmiMethod2() {
    synchronized (mutex) {
        doWhatNeeded2();
    }
}

// in your cleanup thread
void run() {
    synchronized (mutex) {
        cleanUp();
    }
}
2
ответ дан 13 December 2019 в 05:34
поделиться

1) Если я реализую свои удаленные методы RMI методы как синхронизированные, являются ли они гарантированно будут взаимоисключающими? I должен быть уверен, что никакие два из моих RMI-методов (методов, предлагаемых клиентам) не выполняются одновременно.

RMI не обеспечивает такой гарантии сам по себе (в отличие от EJB), и два вызова одного и того же удаленного объекта могут выполняться одновременно, если вы не реализуете некоторую синхронизацию. Ваш подход правильный, и синхронизация всех методов действительно гарантирует, что никакие два из них не будут выполняться одновременно на одном и том же объекте. Примечание: ключевое слово synchronized само по себе эквивалентно synchronized( this ).

2) У меня есть метод, который сервер выполняет периодически. Он используется для очистки. Мне нужно убедиться, что этот конкретный метод не выполняться, когда есть какой-либо метод RMI запускается/используется удаленными клиентами.

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

protected Object lock = new Object();

По традиции для этой цели используется Object. Затем вам нужно захватить блокировку в вашем периодическом задании с помощью synchronized( remoteObj.lock ) { ... }, предполагая, что он находится в том же пакете.

Другие методы в удаленном объекте должны быть синхронизированы таким же образом (synchronized одного недостаточно), чтобы вызовы удаленных методов и периодическое задание были эксклюзивными.

Я рассматривал возможность реализации RMI методы как статические и включить этот метод очистки внутри RMI интерфейс, но это не кажется элегантным способом решения проблемы.

Я также написал метод очистки внутри интерфейса RMI как синхронизированным. Когда я запустил его для тестирования, казалось, что не было коллизий между методами, но я не могу быть уверен.

Если я правильно понял, вы хотите, чтобы логика очистки была статическим методом? Статический метод с synchronized сам по себе захватывает блокировку класса. Обычный" метод с synchronized получает блокировку на экземпляр объекта. Это не одни и те же неявные блокировки!

Но если у вас есть только один инстанцированный удаленный объект, вы можете сделать блокировку статической (Это то же самое, что и блокировка класса, но немного чище). Тогда код очистки тоже может быть статическим и находиться в том же классе, что и удаленный объект, или нет.

Скелет:

public class MyRemoteClass {
   public static Object lock = new Object();

   public void doStuff()
   {
       synchronized( lock ) { ... }
   }
}

public class Cleanup {
   public static void doIt()
   {
       synchronized( MyRemoteClass.lock ) { ... }
   }
}
11
ответ дан 13 December 2019 в 05:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: