2009-11-04 25 views
5

Por favor, señalar/proporcionarme un ejemplo de trabajo del método selector.wakeup(); entre dos hilos.java nio Selector de activación

Intenté crear un programa simple donde un hilo está esperando en el método selector.select(). El segundo subproceso crea algunos sockets e intenta registrarse con el selector; en el que el primer hilo está bloqueado.

Por lo tanto, necesito usar el método selector wakeup, pero de alguna manera el primer hilo no sale del modo de bloqueo.

el Javadoc de estados del método de activación:

Si otro hilo está bloqueado actualmente en una invocación de la Selector.select() o Selector.select métodos (de largo) a continuación, que la invocación volverá inmediatamente.

P.S Hay algunas otras soluciones alternativas; uno de ellos es select (timeout) pero estoy tratando de descubrir dónde está el error.

El pseudo-código:

primer hilo:

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

segundo hilo:

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

} 

Respuesta

4

Es probable que no quieren tener la toma de Thread 2 bloquear si está registrando en un selector (ya que los selectores son para E/S sin bloqueo). Creo que también es una práctica común dejar que el selector maneje la conexión con OP_CONNECT (usando SocketChannel.finishConnection()).

También parece que podría tener una posible condición de carrera aquí. Imagínese esta serie de acontecimientos:

  1. Tema 1: selector.select()
  2. ... el tiempo pasa ...
  3. Tema 2: Thread1.selector.wakeup()
  4. Tema 1: cheques teclas para la aceptabilidad
  5. Tema 1: cheques claves para readibility
  6. Tema 1: bucle
  7. Tema 1: selector.select()
  8. Tema 2: intentar registrar en el selector (pero ya es demasiado tarde para este selecto())

me gustaría sugerir que tiene rosca 2 estableció un SocketChannel, esconderlo en algún lugar del hilo 1 lata hazlo (asegúrate de estar seguro para los hilos cuando hagas esto), luego activa el selector, deja que revise sus claves existentes en el Subproceso 1 y haz que el Subproceso 1 registre el nuevo SocketChannel antes de volver a llamar a Selector.select().

+0

Gracias Seth.Conectarse a otros enchufes es una actividad que ocurriría muy raramente; por lo tanto, deseé de alguna manera que el hilo del selector no verificara alguna colección/variable cada vez que haya actividad en las teclas de selección. – Nilesh

Cuestiones relacionadas