2009-11-04 4 views
5

Veuillez me fournir un exemple de la méthode selector.wakeup(); entre deux fils.java nio Selector wakeup

J'ai essayé de créer un programme simple où un thread attend la méthode selector.select(). Deuxième thread crée des sockets et essaie de s'enregistrer avec le sélecteur; sur lequel le premier thread est bloqué.

D'où j'ai besoin d'utiliser la méthode wakeup du sélecteur, mais en quelque sorte le premier thread n'est pas sorti du mode de blocage.

La javadoc des états méthode réveil par téléphone:

Si un autre thread est actuellement bloqué dans une invocation des méthodes Selector.select() ou Selector.select (long) puis cette invocation retourne immédiatement.

P.S Il existe peu d'autres solutions de rechange; l'un d'eux est select (timeout) mais j'essaie de comprendre où est l'erreur.

Le psuedo-code:

PREMIER FILET:

static Selector selector = Selector.open(); 
while(true) { 
    int n = selectorGlobal.select(); 
    selectorKeySet = selectorGlobal.selectedKeys().iterator(); 
    while (selectorKeySet.hasNext()) { 
     selectionKey = selectorKeySet.next(); 
     if (selectionKey.isReadable()) { 
     //do something 
     } 
     if(selectionKey.isAcceptable()) { 
     //accept 
     } 
    } 
} 

DEUXIÈME FILET:

while (itr.hasNext()) { 
    data = (String) itr.next(); 
    String IP = data.get(0); 
    String Port = data.get(1); 

    SocketChannel socketChannel = SocketChannel.open(); 
    socketChannel.configureBlocking(true); 
    boolean isConnected = socketChannel.connect(new InetSocketAddress(IP, Port)); 
    ClassName.selector.wakeup(); 
    SelectionKey selectionKey = SelectSockets.registerChannel(ClassName.selector, 
       socketChannel, SelectionKey.OP_READ); 

} 

Répondre

4

Vous ne voulez probablement pas avoir la prise de filetage 2 bloquer si vous l'enregistrez dans un sélecteur (car les sélecteurs sont destinés à des E/S non bloquantes). Je pense qu'il est également pratique courante de laisser le sélecteur gérer la connexion avec OP_CONNECT (en utilisant SocketChannel.finishConnection()).

Il semble également que vous pourriez avoir une condition de concurrence potentielle ici. Imaginez cette série d'événements:

  1. Discussion 1: selector.select()
  2. ... le temps passe ...
  3. Discussion 2: Thread1.selector.wakeup()
  4. Discussion 1: chèques clés d'acceptabilité
  5. Fil 1: touches de chèques pour la lisibilité
  6. Fil 1: boucle
  7. Fil 1: selector.select()
  8. Discussion 2: essayez d'enregistrer dans le sélecteur (mais il est trop tard pour cette sélection())

Je suggère d'avoir cette discussion 2 a mis en place un SocketChannel, planquer quelque part cette discussion 1 peut allez-y (assurez-vous d'être sûr de thread lorsque vous faites cela), puis réveillez le sélecteur, laissez-le vérifier ses clés existantes dans Thread 1 et faites en sorte que le thread 1 enregistre le nouveau SocketChannel avant d'appeler Selector.select().

+0

Merci Seth.La connexion à d'autres prises est une activité qui se produirait très rarement; par conséquent, je souhaitais que le thread de sélection ne vérifie pas une collection/variable à chaque fois qu'il y a une activité sur les touches de sélection. – Nilesh