Java RMI 和同步方法

标签 java concurrency synchronization rmi

我正在研究“分布式系统”一书(Tanenbaum 和 Van Steen 合着),他们说的话似乎与许多人对 Java RMI 和同步方法的想法相冲突。

我的想法是,在远程对象实现(因此真正的实现在服务器上运行)上使用同步方法会阻止该方法的并发执行,即使对该方法的调用来自不同的客户端机器(通过代理调用方法...也称为 stub )。

我看到很多人有相同的意见,例如看这里:Java RMI and Thread Synchronization questions

书中反而说使用 RMI 时不会阻止同步方法的并发执行。

这是本书的相关节选(您可以只阅读粗体句子,但如果您愿意,可以阅读上下文):

Logically, blocking in a remote object is simple. Suppose that client A calls a synchronized method of a remote object. To make access to remote objects look always exactly the same as to local objects, it would be necessary to block A in the client-side stub that implements the object's interface and to which A has direct access. Likewise, another client on a different machine would need to be blocked locally as well before its request can be sent to the server. The consequence is that we need to synchronize different clients at different machines. As we discussed in Chap. 6, distributed synchronization can be fairly complex.

An alternative approach would be to allow blocking only at the server. In principle, this works fine, but problems arise when a client crashes while its invocation is being handled by the server. As we discussed in Chap. 8, we may require relatively sophisticated protocols to handle this situation, and which that may significantly affect the overall performance of remote method invocations.

Therefore, the designers of Java RMI have chosen to restrict blocking on remote objects only to the proxies (Wollrath et al., 1996). This means that threads in the same process will be prevented from concurrently accessing the same remote object, but threads in different processes will not. Obviously, these synchronization semantics are tricky: at the syntactic level (ie, when reading source code) we may see a nice, clean design. Only when the distributed application is actually executed, unanticipated behavior may be observed that should have been dealt with at design time. [...]

我认为论文“A Distributed Object Model for the Java System”(available here)在正文中被括号中的注释 Wollrath et all, 1996 引用。然而,我在那篇论文中找到的唯一相关段落是这个:

Due to the differing failure modes of local and remote objects, distributed wait and notification requires a more sophisticated protocol between the entities involved (so that, for example, a client crash does not cause a remote object to be locked forever), and as such, cannot be easily fitted into the local threading model in Java. Hence, a client can use notify and wait methods on a remote reference, but that client must be aware that such actions will not involve the actual remote object, only the local proxy (stub) for the remote object.

我是不是以错误的方式解释了文本,或者实际上是说在使用 RMI 时同步方法“不是那么同步”?

最佳答案

您的第一个引用资料是说,在单个 VM 实例中,对 RMI stub (RMI 服务器的客户端)的调用将在内部同步。也就是说, stub (或代理,文中似乎这样调用它)本身将阻止多个线程同时调用远程服务器上的方法。然而,它澄清了两个 VM,每个 VM 都有远程服务器的 stub ,不会被阻止并发调用远程服务器(这是显而易见的,因为它们不能共享锁,并且 RMI 本身不会阻止服务器的并发)。如果这是不可取的,RMI 服务器将必须实现锁定机制以防止多个并发调用。

第二个引用并不与第一个相矛盾。第二个只是澄清如果您尝试在 stub 上同步,它只会在本地锁定,不会影响远程服务器的并发。

结合两篇文章,我们可以了解到,在 stub 上进行同步将阻止同一 VM 中的多个线程并发访问远程,但不会阻止不同 VM 中的线程并发访问。

关于Java RMI 和同步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3507253/

相关文章:

c++ - 服务和用户模式进程之间的共享全局事件不起作用

java - Spring和Struts可以运行在同一个JVM中吗?

java - 实现条件线程屏障的最佳方式

node.js - Nodejs异步: concurency worker push the same task again in the queue

asp.net - ASP .NET,WCF 并发控制

c - 更好的基准同步

c++ - fwrite 后如何确定数据在磁盘上?

java - 从另一个类和方法返回一个类中的值

Java - 如何使 jButton# 索引采用 int 变量的值?

java - 使用 CMYK 颜色空间在 java 中写入图像