【问题标题】:Using Executor instead of new Thread for Server socket clients对服务器套接字客户端使用 Executor 而不是 new Thread
【发布时间】:2012-04-05 19:18:24
【问题描述】:

我目前正在编写一个服务器,多个客户端将连接到该服务器。通信协议基本上是服务器向客户端发送任务,客户端在执行任务时响应。客户端保持与服务器的连接,并且永远不应断开连接。

目前我正在启动一个新线程来处理每个客户端。在精神上我目前的解决方案是这样的:(来自Java Concurrency in practice

public class ThreadPerTaskWebServer {
    public static void main(String[] args) throws IOException {
        ServerSocket socket = new ServerSocket(80);
        while (true) {
            final Socket connection = socket.accept();
            Runnable task = new Runnable() {
                public void run() {
                    handleRequest(connection);
                }
            };
            new Thread(task).start();
        }
    }

    private static void handleRequest(Socket connection) {
        // request-handling logic here
    }
}

但我想使用 Executor,因为它们看起来更稳定且可扩展性更好。因此,为了让服务器能够向客户端发送消息,我需要将客户端与运行它们的 Executor 分开跟踪。因此,如果我将客户端放在 CopyOnWriteArrayList 客户端中的位置,然后在 Server 类中有类似的内容:

Socket clientSocket = serverSocket.accept();
// The runnable that takes care of a client 
ClientHandler c = new ClientHandler(clientSocket, this);
// Start executing the ClientHandler
exec.execute(c);
// Add clients to CopyOnWriteArrayList
clients.add(c);

这将允许我遍历 CopyOnWriteArrayList 以便向所有客户端发送命令并删除断开连接的客户端。这是一个强大的解决方案吗?如果一个 runnable 出于某种原因会向其传播异常,那么 Executor 会发生什么?

【问题讨论】:

  • 您混淆了客户端和服务器。在您的情况下,客户端是服务器,反之亦然。
  • @ahanin 我同意这不是很清楚,但我认为这是正确的描述。由于客户端连接到服务器(并且它具有 ServerSocket),因此根据定义它成为服务器:)
  • 我并不困惑,我完全理解其意图,我只是想指出@Teletha 正在混淆概念。在所描述的情况下,客户端是一种为“服务器”请求执行任务的工作代理。
  • 你是对的@ahanin。我浏览了第一段。对不起。

标签: java multithreading serversocket executor executors


【解决方案1】:

这是一个可靠的解决方案吗?

是的,我想是的。您需要确保在固定大小的池中分配正确数量的线程或使用动态池。

如果一个 runnable 出于某种原因将异常传播给它,那么 Executor 会发生什么?

如果您的代码抛出RuntimeException,则执行代码的执行器池线程将停止,但池线程计数将减少,并且如果服务尚未关闭,则会创建另一个线程。所以线程池会继续正常运行。

这将允许我遍历 CopyOnWriteArrayList 以便向所有客户端发送命令并删除断开连接的客户端

除非您当然要保存对它们的引用,否则您不需要删除断开连接的那些。否则我无法真正评论这个要求。

【讨论】:

    【解决方案2】:

    如果您选择每个连接方法的线程并且您不想使用 NIO api,我相信这是一个很好的解决方案。但请记住,如果您的池大小小于并发请求的数量,那么您的客户端将等待之前的请求结束。

    关于如果您的任务中出现异常会发生什么:线程终止但执行程序将创建其他线程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-05
      • 2011-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-05
      • 2011-08-15
      相关资源
      最近更新 更多