java rmi死锁

时间:2011-07-26 12:05:33

标签: java synchronization rmi deadlock

我刚开始用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关键字引起的。问题是这些方法必须是同步的(我不想在那里同时使用两个线程),我对如何解决这个问题没有任何想法。任何帮助赞赏。

非常感谢!

2 个答案:

答案 0 :(得分:3)

您可以在每个方法中使用具有不同锁定对象的同步块。 synchronized方法会锁定this,因此一次只能访问一个。

答案 1 :(得分:1)

当您在RMI中进行客户端回调时,它将在与调用执行回调的服务器RMI方法的线程不同的线程上调用。因此,如果回调方法然后在服务器上调用另一个synchronized方法,我们就会出现死锁,因为你已经在服务器上了。因此,如果所有方法调用都是本地而不是远程调用,则synchronized(...)可能会导致死锁。您需要使同步更细粒度:在需要它的实际内部对象上进行同步,而不是通过同步方法在RMI服务器对象本身上进行同步。