Domanda

Si prega di indicare / me fornisce un esempio di lavoro di metodo selector.wakeup(); tra due thread.

Ho cercato di creare un semplice programma in cui un filo è in attesa di metodo selector.select (). Secondo filo crea alcuni prese e tenta di registrare con il selettore; in cui il primo filo è bloccato.

Quindi devo usare il metodo wakeup del selettore, ma in qualche modo il primo depliant filo non esce dalla modalità di blocco.

Il Javadoc del metodo di risveglio afferma:

  

Se un altro filo è attualmente bloccato   in un'invocazione del   Selector.select () o   Selector.select metodi (a lungo) e poi   che invocazione tornerà   immediatamente.

P.S Ci sono pochi altri work-around; uno di loro è select (timeout), ma sto cercando di capire dove l'errore è.

La pseudo-codice:

primo filo:

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
      }
   }
}

secondo filo:

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);

}
È stato utile?

Soluzione

Probabilmente non si vuole avere la presa a partire da fili 2 ostruire se si sta registrando in un selettore (come selettori sono pensati per non-blocking I / O). Penso che sia anche pratica comune per far gestire il selettore del collegamento con OP_CONNECT (utilizzando SocketChannel.finishConnection ()).

Sembra inoltre che si potrebbe avere un potenziale condizione di gara qui. Immaginate questa serie di eventi:

  1. filettatura 1: selector.select ()
  2. ... il tempo passa ...
  3. filettatura 2: Thread1.selector.wakeup ()
  4. filettatura 1: chiavi verifica la presenza di accettabilità
  5. filettatura 1: chiavi verifica la presenza di leggibilità
  6. filettatura 1: ciclo
  7. filettatura 1: selector.select ()
  8. Discussione 2: provare a registrare nel selettore (ma è troppo tardi per questo select ())

Io suggerirei di avere Thread 2 istituito un SocketChannel, riporre via da qualche parte Thread 1 può arrivare a esso (assicuratevi di essere thread-safe quando si esegue questa operazione), poi svegliarsi il selettore, lasciarlo controllare che sia chiavi esistenti nella Discussione 1 e hanno filettatura 1 registrare i nuovi SocketChannel prima di chiamare Selector.select () di nuovo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top