Java RMI 在同一个实例中有不同的值

Java RMI has different values in same instance

我们实现了一个小应用程序,其中客户端调用服务器上的方法。这个想法是服务器保留一个要调用的变量列表,我们在调用后剥离一个值。

在我们的实例中,我们需要让客户端先用 "m1" 调用,然后再用 "m2" 调用。 justReceived 方法(通过 RMI)。

public class Server implements TestService, Serializable {
  private HashMap<String, List<String>> assertQueue = new HashMap<String, List<String>>();

  @Override
  public synchronized void justReceived(Message m, String from, String to) {
    if (!assertQueue.containsKey(to) || !(m instanceof TestMessage))
      return;

    TestMessage message = (TestMessage) m;

    if (assertQueue.get(to).get(0).equals(message.message)) {
      assertQueue.get(to).remove(0);
      System.out.println(assertQueue);//p1
    } else {
      testErrors.add(new AssertionError("Expected " + to + " to receive message " + assertQueue.get(to).get(0) + " but got " + message.message));
    }
  }
}

我们有一个单独的线程监视 assertQueue,但没有观察到任何变化,但我们确信 assertQueue 已通过 RMI 进行了更改。

另一个线程继续打印

{c3=[m1, m2]}

在 p1 打印时:

{c3=[m2]}

即使在 p1 点打印了较小的 assertQueue 之后,另一个线程仍保持相同的打印。

这里没有RMI。这是一个 Serializable 对象,它被传输到客户端并在那里执行。这是问题所在。每个客户端都有一份数据结构的副本,而不是服务器上的一个。

您忘记导出它了。您需要:

  1. 让它扩展 UnicastRemoteObject(),这反过来会迫使您提供一个构造函数,抛出 RemoteException
  2. 导出它 'manually',在调用 bind().
  3. 之前使用 UnicastRemoteObject.exportObject(),

您可以删除 implements Serializable