2009-11-04 11 views
5

Bitte zeigen Sie mir ein Arbeitsbeispiel von selector.wakeup(); Methode zwischen zwei Threads.java nio Selector weckup

Ich habe versucht, ein einfaches Programm zu erstellen, wo ein Thread auf selector.select() -Methode wartet. Der zweite Thread erstellt einige Sockets und versucht, sich mit dem Selektor zu registrieren. auf dem der erste Thread blockiert ist.

Daher muss ich Selectors wakeup Methode verwenden, aber irgendwie kommt der erste Thread isnt nicht aus dem Sperrmodus.

Die Javadoc- der Wakeup-Methode bestimmt:

Wenn ein anderer Thread momentan in einem Aufruf des Selector.select() oder Selector.select (long) Methods dann kehrt dass Aufruf gesperrt sofort.

P.S Es gibt nur wenige andere Arbeitsumgebungen; Einer von ihnen ist ausgewählt (Timeout), aber ich versuche herauszufinden, wo der Fehler liegt.

Der Pseudocode:

erster Thread:

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

zweiter Thread:

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

} 

Antwort

4

Sie wollen wahrscheinlich nicht die Fassung von Thread 2 haben, blockiert werden, wenn Sie es in einem Selektor registrieren (da Selektoren für nicht blockierende E/A bestimmt sind). Ich denke, es ist auch üblich, den Selektor die Verbindung mit OP_CONNECT (mit SocketChannel.finishConnection()) behandeln zu lassen.

Es sieht auch so aus, als könnten Sie hier eine potentielle Race Condition haben. Stellen Sie sich diese Reihe von Veranstaltungen:

  1. Gewinde 1: selector.select()
  2. ... die Zeit vergeht ...
  3. Thread 2: Thread1.selector.wakeup()
  4. Gewinde 1: Kontrollen Schlüssel für Akzeptierbarkeit
  5. Thread 1: checks Tasten für Lesbarkeit
  6. Thread 1: loop
  7. Thread 1: selector.select()
  8. Thread 2: versuchen, in dem Wähler registrieren (aber es ist zu spät für diese select())

Ich würde vorschlagen, mit Thread 2 eine Socket eingerichtet, es bunkern irgendwo Thread 1 kann Machen Sie sich daran (stellen Sie sicher, threadsicher zu sein, wenn Sie dies tun), dann wecken Sie den Selektor, lassen Sie es die vorhandenen Schlüssel in Thread 1 überprüfen und Thread 1 den neuen SocketChannel registrieren, bevor Selector.select() erneut aufgerufen wird.

+0

Danke Seth.Eine Verbindung zu anderen Sockets ist eine Aktivität, die sehr selten passieren würde; daher wünschte ich mir, dass der Selektor-Thread nicht jedes Mal eine Sammlung/Variable überprüfen würde, wenn es eine Aktivität auf den Auswahltasten gibt. – Nilesh

Verwandte Themen