Java ExecutorService ne peut pas être arrêté avec le serveur en cours d’exécution

Je ne sais pas exactement quel est le problème en fermant mon serveur (et ExecutorService). Je démarre le ServerMain et appuyez sur Entrée, ce qui lance la méthode server.shutdown () avec socket.close () mais ne lance pas une exception SocketException. Je ne sais pas si cela est lié au fait que l’ExecutorService ne soit pas capable de s’arrêter. Ceci est le code:

public class ServerMain { public static void main(Ssortingng[] args) throws DirectoryServerException, IOException { TCPDirectoryServer server = new TCPDirectoryServer(); ExecutorService serverExecutor = Executors.newSingleThreadExecutor(); try { server.start(1337); serverExecutor.execute(server); System.out.println("Server started. Press enter to terminate."); System.in.read(); server.shutdown(); System.out.println("Server is shut down..."); } finally { serverExecutor.shutdown(); while (!serverExecutor.isTerminated()) { try { if (!serverExecutor.awaitTermination(5, TimeUnit.SECONDS)) { System.err.println("Problem with shutting down the Executor"); serverExecutor.shutdownNow(); } } catch (InterruptedException ignore) { } } } } } 

Et voici le serveur:

 public class TCPDirectoryServer implements DirectoryServer { private int port; private ConcurrentHashMap cache; private List clientHandlerList; private ExecutorService clientExecutorService; private Socket socket; public TCPDirectoryServer() { super(); this.cache = new ConcurrentHashMap(); this.clientHandlerList = new LinkedList(); this.clientExecutorService = Executors.newCachedThreadPool(); } @Override public void start(int port) throws DirectoryServerException { this.port = port; } @Override public void disconnect(ClientHandler clientHandler) { clientHandlerList.remove(clientHandler); } @Override public void shutdown() throws DirectoryServerException { try { socket.close(); } catch (IOException e) { throw new DirectoryServerException(e); } } @Override public void run() { try (ServerSocket serverSocket = new ServerSocket(port)) { while (true) { socket = serverSocket.accept(); clientHandlerList.add(connect(socket)); } } catch (SocketException e) { System.err.println("AAAA"); System.out.println("Server is shutting down"); } catch (IOException e) { System.out.println("Something failed " + e.getMessage()); } } 

Cette partie:

  while (true) { socket = serverSocket.accept(); clientHandlerList.add(connect(socket)); } 

… ne lancera pas une exception SocketException lorsque vous appelez shutdown , car vous y fermez un socket client (celui qui s’est connecté en dernier). Le ServerSocket est toujours ouvert et attend les demandes entrantes.

L’appel de serverExecutor.shutdown () obligera toujours le serveur à attendre que tous les processus se terminent avant de s’éteindre. C’est un arrêt gracieux. Il attend probablement la boucle “while (true)” pour sortir, ce qui ne semble pas être le cas. Essayez d’appeler serverExecutor.shutdownNow (); pour mettre fin à votre programme.

Dans votre classe TCPDirectoryServer, faites de serverSocket une variable membre et votre méthode d’arrêt devrait ressembler à la suivante

 public void shutdown() { ...... this.serverSocket.close(); ........ } 

De même, lorsque vous fermez un socket client, faites attention à NPE si le socket est null (personne connecté à votre serveur). Cela empêchera également votre serveur de s’arrêter.