And*_*lio 16 java concurrency synchronization rmi
我正在研究"分布式系统"一书(由Tanenbaum和Van Steen撰写),他们说的东西似乎与许多人在Java RMI和同步方法上的想法相冲突.
我认为在远程对象实现上使用synchronized方法(因此在服务器上运行的实际实现)即使对该方法的调用来自不同的客户端机器(通过代理调用该方法),也会阻止该方法的并发执行......又名Stub).
我已经看到很多人有相同的意见,例如在这里看看:Java RMI和线程同步问题
在本书中,它表示使用RMI时不会阻止同步方法的并发执行.
这是本书的相关摘录(您只能阅读粗体句子,但如果您愿意,可以阅读上下文):
逻辑上,远程对象中的阻塞很简单.假设客户端A调用远程对象的同步方法.要使对远程对象的访问看起来与本地对象完全相同,有必要在实现对象接口的客户端存根中阻止A,并且A有直接访问权限.同样,在将其请求发送到服务器之前,还需要在本地阻止另一台机器上的另一个客户端.结果是我们需要在不同的机器上同步不同的客户端.正如我们在Chap中讨论的那样.6,分布式同步可能相当复杂.
另一种方法是仅允许在服务器上进行阻止.原则上,这样可以正常工作,但是当客户端在服务器处理其调用时崩溃时会出现问题.正如我们在Chap中讨论的那样.8,我们可能需要相对复杂的协议来处理这种情况,这可能会显着影响远程方法调用的整体性能.
因此,Java RMI的设计者选择仅限制代理对远程对象的阻塞(Wollrath等,1996).这意味着将阻止同一进程中的线程同时访问同一个远程对象,但不同进程中的线程不会.显然,这些同步语义很棘手:在语法层面(即,在阅读源代码时),我们可能会看到一个漂亮,干净的设计.只有在实际执行分布式应用程序时,才能观察到应该在设计时处理的意外行为.[...]
我认为文章"用于Java系统的分布式对象模型"(此处可用)在文本中通过Wollrath et all, 1996括号之间的注释引用.然而,我在该论文中找到的唯一相关段落就是这一段:
由于本地和远程对象的,分布式的等待和通知的不同故障模式要求所涉及的实体之间的更复杂的协议(使得,例如,一个客户机崩溃不会导致远程对象被永远锁定),并且这样,不能轻易地适应Java中的本地线程模型.因此,客户端可以使用通知,并等待远程的参考方法,但客户必须意识到,这种行为将不涉及实际的远程对象,仅在本地代理(存根)远程对象.
我是以错误的方式解释文本还是事实上说使用RMI时同步方法"不是那么同步"?
mwh*_*den 12
您的第一个参考是,在单个VM实例中,RMI Stub(客户端到RMI服务器)上的调用将在内部同步.也就是说,存根(或代理,如文本似乎称之为)本身将阻止多个线程同时调用远程服务器上的方法.但是,它澄清了两个具有远程服务器存根的虚拟机不会被阻止同时调用远程服务器(这很明显,因为它们不能共享锁,而且RMI本身不会阻止服务器的并发).如果这是不合需要的,则RMI服务器必须实现锁定机制以防止多个并发调用.
第二个参考文献并不反对第一个参考文献.第二个只是澄清,如果您尝试在存根上进行同步,它将仅在本地锁定,并且不会影响远程服务器的并发性.
结合这两个文本,我们可以看到在存根上进行同步将阻止同一VM中的多个线程同时访问远程,但不会阻止不同VM中的线程进行并发访问.
据我所知,对 RMI 服务器的每次调用都会在服务器端创建一个新线程(我的 2000 年日志文件证明了这一点)。如果您在服务器端进行同步,那么您应该是安全的。正如您所发表的,我面临着一些来自文献的古老警告。作为一名实践者,我更喜欢运行该软件一个月左右,并认为它足够稳定,可以用于生产。如果这还不能令人满意,我很抱歉。
| 归档时间: |
|
| 查看次数: |
13081 次 |
| 最近记录: |