2009-11-04 14 views
5

Lütfen iki iş parçacığı arasında bana selector.wakeup(); yönteminin çalışma örneğini işaretleyin/verin.java nio Seçici uyandırma

Bir iş parçacığının selector.select() yönteminde beklediği basit bir program oluşturmaya çalıştım. İkinci iş parçacığı bazı yuvalar oluşturur ve seçiciyle kaydolmaya çalışır; İlk iş parçacığı engellendi.

Bu nedenle, seçicinin wakeup yöntemini kullanmam gerekiyor, ancak bir şekilde ilk iş parçacığı engelleme modundan çıkmıyor.

uyandırma yöntemi durumlarının javadoc: bu çağrı döndürür başka bir iş parçacığı, şu anda daha sonra Selector.select() veya Selector.select (uzun) yöntemleri ile ilgili bir çağırma bloke

halinde hemen.

P.S Diğer birkaç çalışma vardır; bunlardan biri seçilmiştir (zaman aşımı) ama hatanın nerede olduğunu anlamaya çalışıyorum.

psuedo kodu:

İLK İPLİK:

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

İKİNCİ DİŞLİ:

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

} 
Muhtemelen Konu 2'den soketi olmasını istemiyoruz

cevap

4

Bir seçici (eğer seçiciler, engelleme olmayan G/Ç için kullanılır) olarak kaydettiriyorsanız engelleme. Seçicinin OP_CONNECT (SocketChannel.finishConnection() kullanarak) ile bağlantıyı yürütmesine izin vermenin de yaygın bir uygulama olduğunu düşünüyorum.

Ayrıca potansiyel bir yarış durumunuz olabilir gibi görünüyor.

  1. Konu 1: olay serisini düşünün selector.select()
  2. ... zaman geçer ...
  3. Konu 2: Thread1.selector.wakeup()
  4. Konu 1: kabul edilebilirlik denetler tuşları
  5. Konu 1: okunabilirliği denetler tuşları
  6. Konu 1: döngü
  7. Konu 1: selector.select()
  8. Konu 2: uzaklara Konu 1 can Saklayacak, seçicinin kayıt deneyin (ancak bu select() için çok geç) Ben Konu 2 SocketChannel kurmak zorunda öneririm

Bunu yapın (bunu yaparken iş parçacığı güvenli olduğundan emin olun), sonra seçiciyi uyandırın, iş parçacığı 1'deki mevcut anahtarları kontrol etsin ve iş parçacığı 1'i tekrar Selector.select() işlevini çağırmadan önce yeni SocketChannel'i kaydettirin.

+0

Teşekkür ederim Seth.Diğer soketlere bağlanması çok nadiren gerçekleşecek bir aktivitedir; Bu nedenle, seçim iş parçacığı üzerinde etkinlik olduğunda, seçici iş parçacığı her zaman bazı koleksiyonları/değişkenleri denetlememeyi diledi. – Nilesh