Java简单并发服务器

Java简单并发服务器,java,multithreading,concurrency,Java,Multithreading,Concurrency,我必须设计一个简单的服务器,它从多个节点接收消息并将它们存储在消息存储库中 服务器的代码为: public class CommunicationServer implements Runnable { private List<String> messages; private MessageRepository messageRepository; private boolean serverBusy; public Co

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

服务器的代码为:

    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;
  }
}
公共类通信服务器实现可运行{
私人列表消息;
私有消息存储库消息存储库;
私人布尔服务器忙;
公共通信服务器(){
messages=newarraylist();
messageRepository=newmessagerepository();
serverBusy=false;
}
@凌驾
公开募捐{
试一试{
而(!Thread.interrupted()){
已同步(此){
如果(messages.size()>10){
serverBusy=true;
addMessageToRepository();
notifyAll();
}
否则{
serverBusy=false;
等待();
}
}
}
}
捕捉(中断异常e){
System.out.println(e.getMessage());
}
}
公共同步无效接收消息(字符串消息){
if(messages.size()<10){
消息。添加(消息);
}
}
私有void addMessageToRepository(){
如果(messages.size()!=0){
messageRepository.addMessage(messages.remove(0));
}
}
public void showMessageRepository(){
messageRepository.showStoredMessages();
}
公共同步布尔值isServerBusy(){
返回服务器忙;
}
}
节点的代码为:

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();
  }
}
public类节点实现可运行{
私有静态最终字符串字符=“abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyz0123456789”;
专用静态最终整型信息长度=5;
私有随机=新随机();
专用通信服务器通信服务器;
公共节点(通信服务器通信服务器){
this.communicationServer=communicationServer;
}
@凌驾
公开募捐{
试一试{
而(!Thread.interrupted()){
while(communicationServer.isServerBusy()){
等待();
}
receiveMessage(GeneratorDomainString());
}
}
捕捉(中断异常e){
System.out.println(e.getMessage());
}
}
私有字符串生成器domstring(){
StringBuffer randomMessage=新的StringBuffer();
对于(int i=0;i<消息长度;i++){
randomMessage.append(CHARACTERS.charAt(random.nextInt(51));
}
返回randomMessage.toString();
}
}

大体上,我只是为服务器创建一个线程,为节点创建5个线程,并让它们运行一段时间。服务器在收到10条消息之前处于休眠状态,之后必须唤醒以处理消息。问题是我不知道在哪里调用notifyAll()来唤醒负责服务器的线程。

使
通信服务器实现Runnable
没有真正的意义,这暴露了您的基本误解:您用线程标识进程中的参与者(服务器、客户端)。线不是演员;线程是执行参与者代码的地方

因此,在您的
通信服务器中
您说
wait()
时,您不会让服务器等待消息;您可以使该特定线程在服务器对象上作为其监视器等待。同样,如果你说
notifyAll()
,你不是在“通知所有服务器”;您正在通知等待该特定监视器的所有线程。应该是客户端中的一些代码通知当前正在服务器监视器上等待的线程,以及服务器中的一些代码通知正在客户端监视器上等待的线程


一般来说,当您发现自己在同一个同步块中同时使用
wait()
notify()
时,您可以非常确定您的逻辑有问题。

此外,最好有一个处理同步的monitor类,因此,将有一个处理并发性的对象