我刚开始用java rmi编程,我在代码中面临以下问题:
我的服务器有两个远程方法,一般实现如下:
public class ServerImpl extends UnicastRemoteObject implements Server{
....
Synchronized void foo(){ aClient.Foo3();}
Synchronized void foo1(){ .... }
}
我的客户有一个远程方法,实现如下:
public class ClientImpl extends UnicastRemoteObject implements Client{
....
void Foo3(){theServer.foo1();}
}
因此,当aClient调用服务器的foo()时,服务器调用客户端的Foo3(),然后aClient想要调用服务器的foo1(),并且我们有一个死锁(服务器和客户端都没有继续运行)。我知道这是因为Synchronized关键字引起的。问题是这些方法必须是同步的(我不想在那里同时使用两个线程),我对如何解决这个问题没有任何想法。任何帮助赞赏。
非常感谢!
答案 0 :(得分:3)
您可以在每个方法中使用具有不同锁定对象的同步块。 synchronized
方法会锁定this
,因此一次只能访问一个。
答案 1 :(得分:1)
当您在RMI中进行客户端回调时,它将在与调用执行回调的服务器RMI方法的线程不同的线程上调用。因此,如果回调方法然后在服务器上调用另一个synchronized方法,我们就会出现死锁,因为你已经在服务器上了。因此,如果所有方法调用都是本地而不是远程调用,则synchronized(...)可能会导致死锁。您需要使同步更细粒度:在需要它的实际内部对象上进行同步,而不是通过同步方法在RMI服务器对象本身上进行同步。