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
的“常规”方法会在对象实例上抓取锁。这些不是相同的隐式锁!
但是,如果您只实例化了
一个远程对象,则可以使
lock是静态的(这与在类上锁定是相同的,但更加简洁)。清理代码也可以是静态的,并且与远程对象相同或不同类中。
代码框架:
public class MyRemoteClass {
public static Object lock = new Object();
public void doStuff()
{
synchronized( lock ) { ... }
}
}
public class Cleanup {
public static void doIt()
{
synchronized( MyRemoteClass.lock ) { ... }
}
}