Java RMI 和同步方法
我正在研究《分布式系统》(由Tanenbaum和Van Steen撰写)一书,他们说了一些似乎与Java RMI和同步方法上许多人的想法相冲突的东西。
我的想法是,在远程对象实现上使用同步方法(因此在服务器上运行的实际实现)并发执行该方法是被禁止的,即使对该方法的调用来自不同的客户端计算机(通过代理调用该方法...又名存根)。
我看到很多人都有同样的看法,看看这里的例子:Java RMI和线程同步问题
在书中,它说在使用RMI时不会阻止同步方法的并发执行。
以下是本书的相关摘录(您只能阅读粗体句子,但如果您愿意,可以阅读上下文):
从逻辑上讲,远程对象中的阻止很简单。假设客户端 A 调用远程对象的同步方法。若要使对远程对象的访问看起来始终与对本地对象的访问完全相同,有必要在实现对象接口且 A 具有直接访问权限的客户端存根中阻止 A。同样,在将其请求发送到服务器之前,还需要在本地阻止另一台计算机上的另一个客户端。结果是我们需要在不同的机器上同步不同的客户端。正如我们在第 6 章中讨论的那样,分布式同步可能相当复杂。
另一种方法是仅允许在服务器上进行阻止。原则上,这可以正常工作,但是当客户端在服务器处理其调用时崩溃时,就会出现问题。正如我们在第 8 章中所讨论的,我们可能需要相对复杂的协议来处理这种情况,这可能会显著影响远程方法调用的整体性能。
因此,Java RMI的设计者选择将远程对象上的阻塞限制为仅代理(Wollrath等人,1996)。这意味着将阻止同一进程中的线程并发访问同一远程对象,但不同进程中的线程不会。显然,这些同步语义是棘手的:在语法级别(即,在阅读源代码时),我们可能会看到一个漂亮,干净的设计。仅当实际执行分布式应用程序时,才可能观察到应该在设计时处理的意外行为。[...]
我认为论文“Java系统的分布式对象模型”(可在此处获得)在文本中通过括号之间的注释引用。然而,我在那篇论文中发现的唯一相关段落是这个:Wollrath et all, 1996
由于本地和远程对象的故障模式不同,分布式等待和通知需要在所涉及的实体之间使用更复杂的协议(例如,客户端崩溃不会导致远程对象永远锁定),因此,不能轻松地将其放入Java中的本地线程模型中。因此,客户端可以对远程引用使用 notify 和 wait 方法,但该客户端必须知道此类操作不会涉及实际的远程对象,而只涉及远程对象的本地代理(存根)。
我是否以错误的方式解释文本,或者实际上声明同步方法在使用RMI时“不那么同步”?