Java 对服务器套接字客户端使用Executor而不是新线程

Java 对服务器套接字客户端使用Executor而不是新线程,java,multithreading,serversocket,executor,executors,Java,Multithreading,Serversocket,Executor,Executors,我目前正在编写一个服务器,多个客户端将连接到该服务器。通信协议基本上是服务器向客户端发送任务,客户端在执行任务时做出响应。客户端保持与服务器的连接,不应断开连接 目前,我正在启动一个新线程来处理每个客户端。从精神上讲,我目前的解决方案是这样的:(来源) 但我想使用执行器,因为它们看起来更稳定,规模更好。因此,为了使服务器能够向客户机发送消息,我需要将客户机与运行它们的执行器分开进行跟踪。因此,如果我将客户机放在CopyOnWriteArrayList客户机中的位置,然后在服务器类中有类似的内容:

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

目前,我正在启动一个新线程来处理每个客户端。从精神上讲,我目前的解决方案是这样的:(来源)

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

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由于某种原因会向它传播一个异常,那么执行器会发生什么呢

这是一个稳健的解决方案吗

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

如果一个runnable由于某种原因会向它传播一个异常,那么执行器会发生什么呢

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

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


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

如果您选择每个连接的线程方法,并且不想使用NIOAPI,我相信这是一个很好的解决方案。但请记住,如果池大小小于并发请求的数量,则在前一个请求结束之前,您的客户端将处于挂起状态


关于任务中出现异常时会发生什么:线程终止,但executor将创建其他线程。

您正在混淆客户端和服务器。在您的情况下,客户端是服务器,反之亦然。@ahanin我同意这并不完全清楚,但我认为这是最正确的描述。由于客户端连接到服务器(并且它有ServerSocket),它就变成了服务器:)我不感到困惑,我完全理解其意图,我只是想指出@Teletha混淆了概念。在所描述的案例中,客户机是一种工作代理,为“服务器”的任务执行请求提供服务。我浏览了第一段。很抱歉
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);