Si je voulais écrire:Comment détecter un appel Selector.wakeup
int selectedChannels = selector.select(); Set selectedKeys = selector.selectedKeys(); if (selectedChannels != selectedKeys.size()) { // Selector.select() returned because of a call to Selector.wakeup() // so do synchronization. } // Continue with handling selected channels.
serait-il détecter correctement le réveil-appel?
Backgroundinformation:
J'écris un serveur qui la plupart du temps reçoit juste les paquets et les stocke dans un fichier. Très rarement l'application a besoin de s'envoyer un paquet spécial. Pour cela, il établit une connexion (à partir d'un autre thread) à la prise du serveur:
SocketChannel channel = SocketChannel.open(); channel.configureBlocking(false); channel.connect(new InetSocketAddress(InetAddress.getLocalHost(), PORT)); selector.wakeup(); SelectionKey key = channel.register(selector, SelectionKey.OP_CONNECT);
Le problème est que SelectableChannel.register() peut bloquer si le thread principal est déjà dans Selector.select(). Pour éviter cela, j'appelle Selector.wakeup() qui laisse le thread principal revenir prématurément de select(). Pour s'assurer que l'autre thread a la chance de compléter l'appel de registre, je devrais synchroniser le thread principal, mais je devrais le faire après tous les retour de select(). Si je pouvais détecter si elle revenait de select() à cause d'un appel de wakeup(), alors je pourrais l'optimiser pour juste ce cas. Donc, en théorie, l'extrait de code supérieur devrait fonctionner, mais je me demandais s'il ne le ferait que parce qu'il repose sur un comportement non spécifié?
Merci pour tous les conseils.
Quelle est votre motivation pour vouloir éviter les verrous? Est-ce que vous êtes préoccupé par le temps d'exécution, ou appelez-vous select() dans de nombreux endroits et que vous voulez éviter la duplication de code? –
Je suis inquiet au sujet du temps d'exécution, bien que cela puisse être un point discutable puisque select() et register() se synchronisent déjà sur les clés enregistrées. – BugSlayer
D'accord, s'inquiéter de ceci est un exemple classique d'optimisation prématurée. À moins que vous ne parliez vraiment de tolérances de microsecondes, vous ne remarquerez aucun ralentissement. Je vais vomir une réponse en utilisant des verrous. –