J'ai cette structure dommageable: Comme vous pouvez le constater, j'ai besoin de fermer l'auditeur exactement comme je l'ai fait avec la prise. Le problème est que si j'essaie de le faire après la boucle, le code sera "inaccessible", et si j'essaie de déclarer un champ n'importe où pour le serversion, je reçois une nullpointerexception. Je ne veux pas fermer la serversion avec le socket / client car je veux faire de nouvelles connexions. P> Voilà ma question: p> Il est vraiment nécessaire de fermer la servression dans ce cas? Le serversion se ferme par lui-même lorsque le logiciel est fermé? (system.exit (0)) em>. Si la série continue de fonctionner lorsque je ferme le logiciel simplement parce que je ne l'ai pas fermé, j'ai un problème, car je ne peux pas atteindre ce morceau de code sanglant pour la fermer :). P> P>
3 Réponses :
Oui. Tout en détruisant des références à la prise May em> provoquer la finalisation du collecteur des ordures, cela ne précise pas qu'il sera fermé. Ceci est spécifique de la mise en œuvre dans de nombreux cas et peut parfois se dérailler par rapport à la conception en raison de la performance ou même des insectes minuscules difficiles à suivre. P>
Garder une référence Anywhere em> est un sûr em> parie que ce n'est pas, même avec des faiblesFérences. P>
Maintenant, le système d'exploitation est limité (en raison de sa conception) de sockets qu'il peut donner. Lorsque vous ouvrez de plus en plus de sockets, le système d'exploitation est sous pression et fonctionne éventuellement de sockets, entraînant une défaillance de Java ou d'un autre programme. De plus, émettant des options de socket que vous ou les défauts peuvent définir, cette prise peut envoyer des conserves, des ressources épuisantes sur l'autre point d'extrémité. P>
À la sortie, il est fermé par la prise enregistrant une action d'arrêt dans son constructeur pour la fermer et / ou le nettoyage automatique du système d'exploitation. P>
vous devriez jamais em> s'appuyer sur le comportement OS / JVM ou la finalisation pour fermer vos sockets, strong> surtout si vous avez plusieurs sockets, même si vous ne prévoyez pas d'utiliser tous d'entre eux en même temps. P>
Oui, il est nécessaire de libérer les ressources finies, car sinon votre application rendra d'autres processus sur l'hôte Smart pour les ressources et ne pourra pas soutenir à long terme
Voici comment je fais une telle tâche:
public void run() { ServerSocket serverSocket = null; try { serverSocket = ... // init here } catch (...) { } finally { if (serverSocket != null) { try { serverSocket.close(); } catch (IOException e) { // log error just in case } } } }
Je suggérerais d'utiliser le code Java 7 ici, en particulier les ressources try-with-with-whis: essayer (serversocket = ...) {...} Catch (...) {...} code> Ce qui fait efficacement la même chose, dans de nombreuses lignes.
Une réponse est que vous devez vraiment pourquoi? p> Parce que, les circonstances qui (hypothétiquement) signifient qu'il n'est pas strictement nécessaire et ... laisse face Il ... c'est easy em> pour écrire du code pour fermer automatiquement une prise de serveur. P> mais lu sur ... P> Il est vraiment nécessaire de fermer la servression dans ce cas? P>
blockQuote> Cela dépend. P> si vous savez pour certains em> que sinon, l'échec de la fermeture () pourrait em> causer des dommages. p> li>
ul> Le "dommage" pourrait prendre quelques formes: p> La prise de serveur peut contenir un "verrou" sur un port, empêchant ainsi une autre instance de l'application d'écouter sur ce port (selon le système d'exploitation). P> li>
La prise de serveur pourrait être une ressource limitée, et si la méthode Le préjudice pourrait également être infligé à l'instance d'application elle-même, si Le serversocket se ferme par lui-même lorsque le logiciel est arrêté? P>
BlockQuote> Le serreSocket ne "ferme pas" à moins que ce ne soit recueilli et finalisé. Et vous ne pouvez pas compter sur l'événement lorsque un JVM sort. Mais dans un sens plus large, la ressource de prise de serveur sous-jacente est typiquement em> fermée automatiquement lorsque le JVM sort. P> mais la réponse complète dépend en fait de ce que vous entendez par " Le logiciel est fermé », ainsi que sur la nature de la plate-forme. Par exemple: p> Si l'arrêt signifie que le JVM sort complètement et le processus correspondant qui "possède" la prise de serveur sous-jacente (à partir du point de vue du système d'exploitation) aussi em> les sorties, puis le système d'exploitation fermera cette prise ... au moins sur les plates-formes modernes Unix / Linux / Windows. (Notez que Android est Linux sous la hotte) P> Li>
si "le logiciel" est quelque chose comme une webApp exécutée dans un conteneur Web, "l'arrêt" peut signifier quelque chose de différent de la sortie JVM et que le serversocket pourrait continuer à exister (et ne pas être fermé) après l'arrêt . P> li>
Si la JVM est intégrée à quelque chose d'autre (par exemple dans une grande application C / C ++) et que quelque chose d'autre ne quitte pas, le système d'exploitation ne saura pas libérer la prise de serveur sous-jacente. P > li>
Si vous exécutez sur la plate-forme où le système d'exploitation ne fournit pas le même niveau de séparation de processus / gestion des ressources que sur des fenêtres UNIX / Linux / (modernes), la prise de serveur sous-jacente peut ne pas être em> fermé par le système d'exploitation sur la sortie du processus. (Ce scénario pourrait demander une implémentation Java sur un système intégré ...) p> li>
ul> en tout cas, il n'est pas difficile de faire la bonne chose. En Java 7 et plus tard: P> fermer () code> ressources ... même si ce n'est pas strictement nécessaire.
exécution () code> ne sera jamais exécuté une fois et que l'application va toujours complètement éteindre (Modulo Cavales ci-dessous), alors ne fermez pas la fermeture de la touche
code> ne causera aucun mal réel. p> li>
exécuter () code> est appelée plusieurs fois (sans
fermer () code> -ing). pourrait "saisir" toutes les instances disponibles de cette ressource, empêchant ainsi les autres applications d'acquérir une instance. P> LI>
ul>
exécuter () code> est appelé plusieurs fois. p>
public void run() {
String p = portField.getText().trim();
if (p.isEmpty()) {
return;
}
btnRun.setEnabled(false);
try (ServerSocket listener = new ServerSocket(Integer.parseInt(p))) {
while (true) {
try (Socket socket = listener.accept();
PrintWriter out = new PrintWriter(
socket.getOutputStream(), true)) {
out.println("Hi there, human.");
}
}
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(null, "Only numbers are allowed.");
} catch (HeadlessException | IOException e) {
e.printStackTrace();
} finally {
btnRun.setEnabled(true); // ... possibly
}
}
En un seul mot, oui.