Si vous envoyez toujours l'exécution à un pool de threads après le retour de select(), vous souhaiterez peut-être annuler immédiatement la clé, puisque vous perdez le contrôle pendant la durée d'exécution du Runnable. Ex.: Si vous effectuez la sélection suivante() avant d'annuler la clé précédente (le thread est toujours en attente d'exécution), il sera encore valide, ce qui entraînera l'exécution par un autre thread de la clé déjà envoyée. Si l'un de ces threads annule la clé, l'autre obtiendra un CancelledKeyException en plus d'introduire un comportement inattendu.
Même si vous annulez la touche, un thread peut enregistrer le même canal (mettre à jour les touches de sélection) avant que le canal ne soit désenregistré (en raison de votre précédente key.cancel()
). Que, encore une fois, provoquera un CancelledKeyException.
Pour se débarrasser de ce piège, vous pouvez gérer les événements toujours dans la boucle suivante:
while (true) { // true or something less risky
//for each pendingTasks call
pool.execute(task);
Iterator<SelectionKey> iter = selector.selectedKeys().iterator();
while (iter.hasNext()) {
SelectionKey key = iter.next();
iter.remove();
key.cancel();
//store dispatch for the next while iteration
pendingTasks.add(task); // do not execute tasks before next select()
}
selector.select(TIMEOUT); // or selectNow if there are
//any pending events to handle.
}
exécution Firt sera, presque, jamais remettre les clés, mais le select() à la fin de votre loop MAY garantir que le canal de la touche annulée soit désenregistré (porter à votre discrétion) du sélecteur. Cependant, si vous exécutez simplement une tâche dans le même thread, vous écoutez vos événements de sélection, la mise à jour des sons est plus simple et plus sûre.
vous pouvez modifier le délai d'attente de votre sélecteur s'il existe des tâches en cours d'exécution sur votre pool de threads.Si vous utilisez un gros timout dans select(), vous pouvez provoquer des threads bloqués pour l'enregistrement de canaux nouveaux/existants dans le sélecteur. – paulosuzart