Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

239
Visualizações
ThreadPoolExecutor.shutdownNow() no lanza InterruptedException en Thread

Estoy implementando un programa Transfer Server que toma mensajes de los clientes (a través de la entrada de la consola) y luego los reenvía a algún tipo de buzón.

Para permitir la recepción simultánea de varios mensajes por diferentes clientes, primero creé una clase que implementa la interfaz Runnable . Cada una de las instancias de esta clase manejará la comunicación con exactamente un cliente:

 public class ClientConnection implements Runnable { //... //... @Override public void run() { try { // prepare the input reader and output writer BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); PrintWriter writer = new PrintWriter(clientSocket.getOutputStream(), true); Message message = new Message(); String request = ""; // read client requests while ((request = reader.readLine()) != null) { System.out.println("Client sent the following request: " + request); String response; if (request.trim().equals("quit")) { writer.println("ok bye"); return; } response = message.parseRequest(request); if (message.isCompleted()) { messagesQueue.put(message); message = new Message(); } writer.println(response); } } catch (SocketException e) { System.out.println("ClientConnection: SocketException while handling socket: " + e.getMessage()); } catch (IOException e) { throw new UncheckedIOException(e); } catch (InterruptedException e) { System.out.println("Client Connection was interrupted!"); e.printStackTrace(); } finally { if (clientSocket != null && !clientSocket.isClosed()) { try { clientSocket.close(); } catch (IOException ignored) {} } } } }

Tengo un subproceso principal que es responsable de iniciar y administrar todos los ejecutables de ClientConnection:

 @Override public void run() { clientConnectionExecutor = (ThreadPoolExecutor) Executors.newCachedThreadPool(); while (true) { Socket clientSocket; try { // wait for a Client to connect clientSocket = serverSocket.accept(); ClientConnection clientConnection = new ClientConnection(clientSocket, messagesQueue); clientConnectionExecutor.execute(clientConnection); } catch (IOException e) { // when this exception occurs, it means that we want to shut down everything clientConnectionExecutor.shutdownNow(); // force terminate all ClientConnections return; } } }

Ahora, de acuerdo con esta pregunta de Stackoverflow , hubiera esperado que tan pronto como shutdownNow(); se está llamando, se lanzaría una InterruptedException dentro de mi método ClientConnection.run() , y allí, debería imprimir Client Connection was interrupted! . Pero esto no sucede, por lo que parece que nunca se alcanza la cláusula catch, el bucle de lectura de entrada simplemente continúa.

Leí en otra pregunta de Stackoverflow que esto podría estar relacionado con alguna otra línea de código dentro del bloque que parece estar consumiendo la excepción InterruptedException , pero no había ninguna información particular sobre qué línea de código podría hacer eso. Así que estoy agradecido por cualquier pista.

Editar: resulta que tan pronto como salgo manualmente del ciclo escribiendo "salir" en el cliente, el ciclo se cerrará y luego, Client Connection was interrupted! será impreso. Entonces, de alguna manera, la excepción parece ignorarse mientras el ciclo se está ejecutando y solo se maneja después.

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Habría esperado que tan pronto como shutdownNow(); se está llamando, se lanzaría una InterruptedException dentro de mi ClientConnection.run()

Tu messagesQueue debe ser un BlockingQueue . Por lo tanto messagesQueue.put(message) hará que necesite detectar una excepción Interrupted . Entonces, solo cuando el subproceso está bloqueado en el método put (la queue está llena), llama a threadpool#shutdownNow , luego el subproceso recibirá una excepción Interrupted . En otros casos, el subproceso no recibirá esta excepción Interrupted .

Puede cambiar while ((request = reader.readLine()) != null) a while ((request = reader.readLine()) != null && !Thread.interrupted()) .

Otra solución es mantener todos los sockets de clientes y cerrar todos los sockets de clientes cuando necesite cerrarlos, de esta manera, el subproceso del cliente recibirá directamente una IOException :

 List<Socket> clientSockets = new ArrayList<>(); while (true) { try { Socket accept = serverSocket.accept(); clientSockets.add(accept); executorService.submit(new ClientConnection(accept)); }catch (Exception e) { for (Socket socket : clientSockets) { try { socket.close(); } catch (Exception exception) { // } } //executorService.shutdownNow(); } }
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda