【问题标题】:How to notify all Threads after receiving input接收输入后如何通知所有线程
【发布时间】:2020-04-16 08:54:19
【问题描述】:

我目前正在开发一些东西,我有一个服务器等待连接,一旦建立连接,就会创建一个线程来处理服务器和客户端之间的通信。所有这些通信都是基于字符串的,使用 InputStreamReaders 和 OutputStreamReaders,我现在需要做的是能够通过他们自己的 ServerThread 向每个连接的客户端发送消息。写东西的一个简单观点是:

public final static int SERVER_PORT = 12345;   
private static int numThreads=0;

public void Server() {
    ServerSocket serverSocket = null;
    
    try{
        serverSocket = new ServerSocket(Server.SERVER_PORT);           
    } catch (IOException e) {
        e.printStackTrace();
        System.exit(-1);
    }

    while (true) {
        try {
            Socket socket = serverSocket.accept();
            numThreads++;
            new ServerThread(socket, numThreads).start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

变量numThreads主要用于向客户端打印特定信息。在ServerThread 我会:

@Override
public void run() {
    while (true) {
        String command=null;
        try{
            command = readString(); //method that reads input from Client
            //Do actions based on command
        }catch(Exception ex){
            ex.getMessage();                    
        }
    }
    //Close streams and socket
}

显示的方法的内容可能有一些拼写错误,因为目前还有很多,但应该有助于将问题可视化。

为了简化客户端,我们假设有一个客户端,它连接到服务器并向我们的ServerThread 发送命令/消息。

每次Client连接到Server时,都会创建一个新的ServerThread,它会不断等待Client发送command。如果这个command 对应,例如,“发送”,我需要向连接到服务器的每个客户端发送一条消息。

我怎么能做到这一点?

【问题讨论】:

    标签: java multithreading sockets server client


    【解决方案1】:

    这里我提供一个思路,可以通过事件监控(观察者模式)来解决。
    可以将发布者分成单独的类。

    public class ServerThread implements Runnable {
    
      // Used for event subscription (CopyOnWriteArrayList is not the best implementation, please adjust
      // according to project needs)
      private static final List<ServerThread> LISTENERS = new CopyOnWriteArrayList<>();
    
      public ServerThread(Socket socket, int num) {
        // do something ...
        LISTENERS.add(this);
      }
    
      @Override
      public void run() {
        while (true) {
          String command = null;
          try {
            command = readString(); // method that reads input from Client
            // Do actions based on command
            if ("send".equals(command)) {
              ServerThread.publish(new SendEvent(command));
            }
          } catch (Exception ex) {
            ex.printStackTrace();
          }
        }
        // Close streams and socket
      }
    
      private String readString() {
        return null;
      }
    
      /**
       * event publishing method
       *
       * @param event
       */
      public static void publish(SendEvent event) {
        LISTENERS.forEach(listener -> listener.listen(event));
      }
    
      /**
       * Event processing method
       *
       * @param event
       */
      public void listen(SendEvent event) {
        // to something ...
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-02
      • 1970-01-01
      • 2015-05-18
      • 2017-08-01
      • 1970-01-01
      • 2011-02-27
      相关资源
      最近更新 更多