Java RMI и синхронизированные методы

Я изучаю книгу «Распределенные системы» (Таненбаум и Ван Стин), и они говорят что-то, что кажется противоречащим тому, что кажется вместо этого многие думали о Java RMI и синхронизированных методах.

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

Я видел, что многие люди придерживаются того же мнения. Посмотрите, например, здесь: Вопросы по Java RMI и синхронизации потоков

В книге вместо этого сказано, что одновременное выполнение синхронизированных методов не предотвращается, когда используя RMI.

Вот соответствующий отрывок из книги (вы можете прочитать только выделенное жирным шрифтом предложение, но вы можете прочитать контекст, если хотите):

Логически заблокировать удаленный объект просто. Предположим, что клиент A вызывает синхронизированный метод удаленного объекта . Чтобы доступ к удаленным объектам всегда выглядел точно так же , что и к локальным объектам, необходимо заблокировать A в клиентской заглушке, которая реализует интерфейс объекта , к которому A имеет прямой доступ . Аналогичным образом, другой клиент на другом компьютере также должен быть заблокирован локально , прежде чем его запрос может быть отправлен на сервер . В результате нам необходимо синхронизировать разных клиентов на разных машинах. Как мы обсуждали в гл. 6, распределенная синхронизация может быть довольно сложной.

Альтернативный подход - разрешить блокировку только на сервере. По принципу это работает нормально, но проблемы возникают, когда клиент дает сбой , когда его вызов обрабатывается сервером. Как мы обсуждали в гл. 8, нам могут потребоваться относительно сложные протоколы для обработки этой ситуации, которые могут существенно повлиять на общую производительность удаленного метода призывы.

Поэтому разработчики Java RMI решили ограничить блокировку удаленных объектов только прокси-серверами (Wollrath et al., 1996). Это означает, что потоки одного процесса не смогут одновременно обращаться к одному и тому же удаленному объекту, но потоки в разных процессах будут нет. Очевидно, эта семантика синхронизации сложна: на синтаксическом уровне (т. Е. При чтении исходного кода) мы можем увидеть красивый чистый дизайн. Только , когда распределенное приложение фактически выполняется, может наблюдаться непредвиденное поведение, которое нужно было устранить во время разработки. [ ...]

Я думаю, что статья «Распределенная объектная модель для системы Java» ( доступна здесь ) упоминается в тексте в примечании Wollrath et all, 1996 в скобках. Однако единственный релевантный абзац, который я нашел в этой статье, - это:

Из-за различных режимов отказа локальных и удаленных объектов для распределенного ожидания и уведомления требуется более сложный протокол. между вовлеченными объектами (так, чтобы, например, сбой клиента не приводил к блокировке удаленного объекта навсегда), и, как , не может быть легко встроен в модель локальных потоков в Java. Следовательно, клиент может использовать методы notify и wait для удаленной ссылки, но этот клиент должен знать, что такие действия не будут включать фактический удаленный объект , а только локальный прокси (заглушка) для удаленного объекта .

Я неправильно интерпретирую текст или на самом деле утверждается, что синхронизированные методы «не так синхронизированы» при использовании RMI?

16
задан Community 23 May 2017 в 11:48
поделиться

2 ответа

Насколько мне известно, каждый вызов RMI-сервера создает новый поток (о чем свидетельствуют мои файлы журнала с 2000 года) на стороне сервера. Если вы выполняете синхронизацию на стороне сервера, вы должны быть в безопасности. Когда вы писали, я столкнулся с некоторыми древними предупреждениями из литературы. Как практик, я предпочел запустить программу около месяца и решил, что она достаточно стабильна для работы. Извините, если это вас не устраивает.

1
ответ дан 30 November 2019 в 22:55
поделиться

Вы также должны знать, что многопоточность Java значительно изменилась с 1996 года. Методы notify () и wait (), которые были частью оригинальной языковой конструкции, сильно пострадали от параллелизма. эксперты и в Java 5 (2004, говорит wiki) были введены высокоуровневые объекты параллелизма , такие как ReentrantLock , которые в настоящее время являются предпочтительным способом работы.

Итак, приведенная вами критика, вероятно, верна, но устарела.

1
ответ дан 30 November 2019 в 22:55
поделиться
Другие вопросы по тегам:

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