1) 如果我将我的 RMI 远程方法实现为同步的,它们是否保证是互斥的?我需要确保没有两个 RMI 方法(提供给客户的方法)同时执行。
RMI 本身不提供这样的保证(与 EJB 不同),并且对同一个远程对象的两个调用可能会同时执行,除非您实现了一些同步。您的方法是正确的,并且同步所有方法确实可以确保它们中的任何一个都不会同时在同一个对象上运行。注意:synchronized
单独的关键字等同于synchronized( this )
.
2)我有一个服务器定期执行的方法。它用于进行清理。当远程客户端正在运行/使用任何 RMI 方法时,我必须确保不会执行此特定方法。
如果清理作业在另一个类中,您将需要定义一个锁,您将在远程对象和清理作业之间共享该锁。在远程对象中,定义一个将用作锁的实例变量。
protected Object lock = new Object();
按照惯例,人们Object
为此目的使用一个。synchronized( remoteObj.lock ) { ... }
然后,假设它在同一个包中,您需要使用 来锁定您的定期工作。
远程对象中的其他方法将需要以相同的方式同步(synchronized
单独是不够的),以便远程方法调用和定期作业都是互斥的。
我考虑过将 RMI 方法实现为静态方法,并在 RMI 接口中包含该清理方法,但这似乎不是解决问题的优雅方法。
我还在 RMI 接口中编写了同步的清理方法。当我运行它进行测试时,方法之间似乎没有冲突,但我不能确定。
如果我理解得很好,您想让清理逻辑成为静态方法吗?synchronized
一个单独的静态方法获取类的锁。“常规”方法synchronized
在对象实例上获取锁。这些不是相同的隐式锁!
但是,如果您只实例化了一个远程对象,则可以将锁设为静态(这与锁定类相同,但更简洁一些)。然后,清理代码也可以是静态的,并且与远程对象是否在同一个类中。
骨骼:
public class MyRemoteClass {
public static Object lock = new Object();
public void doStuff()
{
synchronized( lock ) { ... }
}
}
public class Cleanup {
public static void doIt()
{
synchronized( MyRemoteClass.lock ) { ... }
}
}