Java简单并发服务器

时间:2015-02-27 08:07:52

标签: java multithreading concurrency

我必须设计一个简单的服务器,它接收来自多个节点的消息并将它们存储在消息库中。

服务器的代码是:

    public class CommunicationServer implements Runnable {
      private List<String> messages;
      private MessageRepository messageRepository;
      private boolean serverBusy;

      public CommunicationServer() {
       messages = new ArrayList<String>();
       messageRepository = new MessageRepository();
       serverBusy = false;
     }

      @Override
      public void run() {
      try {
       while (!Thread.interrupted()) {
        synchronized (this) {
          if (messages.size() > 10) {
            serverBusy = true;
            addMessageToRepository();
            notifyAll();
          }
          else {
            serverBusy = false;
            wait();
          }
        }
      }
    }
    catch (InterruptedException e) {
      System.out.println(e.getMessage());
     }
    }

    public synchronized void receiveMessage(String message) {
     if (messages.size() < 10) {
      messages.add(message);
    }
    }

  private void addMessageToRepository() {
    if (messages.size() != 0) {
      messageRepository.addMessage(messages.remove(0));
    }
  }

  public void showMessageRepository() {
    messageRepository.showStoredMessages();
  }

  public synchronized boolean isServerBusy() {
    return serverBusy;
  }
}

节点的代码是:

public class Node implements Runnable {
  private static final String CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ0123456789";
  private static final int MESSAGE_LENGHT = 5;
  private Random random = new Random();
  private CommunicationServer communicationServer;

  public Node(CommunicationServer communicationServer) {
    this.communicationServer = communicationServer;
  }

  @Override
  public void run() {
    try {
      while (!Thread.interrupted()) {
        while (communicationServer.isServerBusy()) {
          wait();
        }
        communicationServer.receiveMessage(generateRandomString());
      }
    }
    catch (InterruptedException e) {
      System.out.println(e.getMessage());
    }
  }

  private String generateRandomString() {
    StringBuffer randomMessage = new StringBuffer();

    for (int i = 0; i < MESSAGE_LENGHT; i++) {
      randomMessage.append(CHARACTERS.charAt(random.nextInt(51)));
    }
    return randomMessage.toString();
  }
}

在main中我只为服务器创建一个线程,为节点创建5个线程,让它们运行一段时间。服务器休眠直到收到10条消息,之后必须唤醒它才能处理消息。问题是我无法弄清楚在哪里调用notifyAll()以唤醒负责服务器的线程。

1 个答案:

答案 0 :(得分:1)

CommunicationServer implements Runnable真的没有意义,并暴露了你的基本误解:你用线程 actors >。线程不是演员;一个线程是演员代码被执行的地方。

因此,当您在CommunicationServer中说wait()时,您不会让服务器等待消息;您将该特定的线程等待服务器对象作为其监视器。同样,那么你说notifyAll(),你不是&#34;通知所有服务器&#34 ;;您正在通知在该特定监视器上等待的所有线程。它应该是客户端中的一些代码,它通知当前正在服务器监视器上等待的线程,以及服务器中的一些代码,通知在客户端监视器上等待的那些代码。

作为一般经验法则,当您发现自己在同一个同步块中同时使用wait()notify()时,您可以非常确定您的逻辑存在问题。< / p>