问题描述
我正在研究分布式系统一书(由Tanenbaum& Van Steen撰写),他们说的东西似乎与许多人在Java RMI和同步方法上的想法相冲突。
I'm studying the book "Distributed Systems" (by Tanenbaum & Van Steen) and they say something that seems to conflict to what seems to be instead thought by many on Java RMI and synchronized methods.
我认为在远程对象实现上使用 synchronized方法(因此在服务器上运行的实际实现),即使在对该方法的调用来自不同的客户端机器(通过代理调用方法...也称为存根)。
What I thought is that using a synchronized method on a Remote Object implementation (so the real implementation running at the server) concurrent execution of that method is prevented even when the calls to that method are from different clients machines (calling the method via a Proxy... aka a Stub).
我看过很多人都有同样的观点,请看这里例如:
I've seen that a lot of people have the same opinion, look here for example: Java RMI and Thread Synchronization questions
在本书中,它表示使用RMI时不会阻止同步方法的并发执行。
In the book it's instead said that concurrent execution of synchronized methods is not prevented when using RMI.
这是书中的相关摘录(你可以重新仅使用粗体句子,但如果您愿意,可以阅读上下文:
Here's the relevant excerpt from the book (you can read the bold sentence only, but you can read the context if you prefer to):
另一种方法是
允许仅在服务器上阻塞。在
原则中,这工作正常,但是当客户端在服务器处理
的调用时崩溃
时会出现
问题。正如我们在
中所讨论的那样。 8,我们可能需要相对
复杂的协议来处理这个
的情况,而这可能
显着影响远程方法
调用的整体
性能。
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.
因此,Java RMI
的设计者已经选择将
远程对象的阻塞限制为仅代理
(Wollrath等人) 。,1996)。这意味着
同一进程中的线程将同时阻止
访问同一个远程对象
,但不同进程中的
线程将不会
。显然,这些同步
语义是棘手的:在语法
级别(即,在阅读源代码时)
我们可能会看到一个漂亮,干净的设计。当分布式应用程序实际执行
时,只有
,如果
已在设计时处理,则可能会出现意外的
行为。
[...]
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. [...]
我认为文章Java系统的分布式对象模型()在文本中以注释<$ c引用$ c> Wollrath等,1996 括号之间。然而,我在该论文中找到的唯一相关段落是这一段:
I think that the paper "A Distributed Object Model for the Java System" (available here) is referenced in the text by the note Wollrath et all, 1996
between parenthesis. However the only relevant paragraph I've found on that paper is this one:
我是以错误的方式解释文本还是事实上声明了同步方法使用RMI时不是那么同步?
Am I interpreting the text in the wrong way or is in fact stated that synchronized methods are "not so synchronized" when using RMI?
推荐答案
您的第一个参考资料是在单个VM实例中调用在RMI Stub(客户端到RMI服务器)上将在内部同步。也就是说,存根(或代理,如文本似乎称之为)本身将阻止多个线程同时调用远程服务器上的方法。但是,它澄清了两个具有远程服务器存根的虚拟机不会被阻止同时调用远程服务器(这很明显,因为它们不能共享锁,而且RMI本身不会阻止服务器的并发)。如果这是不合需要的,RMI服务器必须实现一个锁定机制来防止多个并发调用。
What your first reference is saying is that within a single VM instance, invocations on an RMI Stub (client to an RMI server) will be internally synchronized. That is, the stub (or proxy, as the text seems to call it) itself will prevent multiple threads from concurrently invoking a method on the remote server. It clarifies, however, that two VMs each with stubs for a remote server will not be blocked from concurrently invoking the remote server (which is obvious, because they cannot share a lock, and RMI itself does not prevent concurrency at the server). If this is undesirable, the RMI server will have to implement a locking mechanism to prevent multiple concurrent invocations.
第二个引用不会与第一个引用相矛盾。第二个只是说明如果你尝试在存根上进行同步,它只会在本地锁定,并且不会影响远程服务器的并发性。
The second reference does not in anyway contradict the first. The second merely clarifies that if you try to synchronize on a stub, it will only be locked locally, and will not impact the concurrency of the remote server.
将两者结合起来我们可以看到,在存根上同步会阻止同一个VM中的多个线程同时访问远程,但不会阻止不同虚拟机中的线程同时访问。
Combining the two texts, we can read that synchronizing on a stub will prevent the multiple threads in the same VM from concurrently accessing the remote, but will not prevent threads in distinct VMs from concurrent access.
这篇关于Java RMI和同步方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!