2009-11-04 4 views
5

कृपया मुझे दो थ्रेड के बीच selector.wakeup(); विधि का एक कार्य उदाहरण प्रदान करें।जावा एनओ सिलेक्टर वेकअप

मैंने एक साधारण प्रोग्राम बनाने की कोशिश की जहां थ्रेड selector.select() विधि पर प्रतीक्षा कर रहा है। दूसरा धागा कुछ सॉकेट बनाता है और चयनकर्ता के साथ पंजीकरण करने की कोशिश करता है; जिस पर पहला धागा अवरुद्ध है।

इसलिए मुझे चयनकर्ता की wakeup विधि का उपयोग करने की आवश्यकता है, लेकिन किसी भी तरह पहला थ्रेड ब्लॉकिंग मोड से बाहर नहीं आता है।

Wakeup विधि राज्यों के जावाडोक:

तो एक और धागा वर्तमान में Selector.select() या Selector.select (लंबी) के तरीकों में से एक मंगलाचरण में अवरुद्ध है तो कि मंगलाचरण वापस आ जाएगी तुरंत।

पीएस कुछ अन्य काम-आसपास हैं; उनमें से एक चुनिंदा (टाइमआउट) है लेकिन मैं यह पता लगाने की कोशिश कर रहा हूं कि गलती कहां है।

छद्म-कोड:

पहले थ्रेड:

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

दूसरा थ्रेड:

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

} 

उत्तर

4

आप शायद थ्रेड 2 से सॉकेट है नहीं करना चाहते यदि आप इसे किसी चयनकर्ता में पंजीकृत कर रहे हैं तो अवरुद्ध हो जाएं (क्योंकि चयनकर्ता गैर-अवरुद्ध I/O के लिए हैं)। मुझे लगता है कि चयनकर्ता को OP_CONNECT (SocketChannel.finishConnection() का उपयोग करके) को जोड़ने के लिए चुनौती देना भी आम बात है।

ऐसा लगता है कि यहां आपकी संभावित दौड़ स्थिति हो सकती है।

  1. थ्रेड 1: घटनाओं की इस श्रृंखला की कल्पना selector.select()
  2. ... समय गुजरता है ...
  3. थ्रेड 2: Thread1.selector.wakeup()
  4. थ्रेड 1: स्वीकार्यता के लिए जाँच करता है कुंजी
  5. थ्रेड 1: readibility के लिए चेक कुंजी
  6. थ्रेड 1: पाश
  7. थ्रेड 1: selector.select()
  8. थ्रेड 2: चयनकर्ता में रजिस्टर करने की कोशिश (लेकिन यह इस का चयन करें() के लिए बहुत देर हो चुकी)

मैं थ्रेड 2 एक SocketChannel की स्थापना होने सुझाव देंगे, यह भी छिपा सकते दूर कहीं थ्रेड 1 कर सकते हैं इसे प्राप्त करें (जब आप ऐसा करते हैं तो थ्रेड सुरक्षित होना सुनिश्चित करें), फिर चयनकर्ता को जगाएं, इसे थ्रेड 1 में मौजूदा कुंजी की जांच करें और थ्रेड 1 को नया सॉकेट चैनल पंजीकृत करें इससे पहले कि वह selector.select() को कॉल करें।

+0

धन्यवाद सेठ।अन्य सॉकेट से कनेक्ट करना एक ऐसी गतिविधि है जो बहुत ही कम हो रही है; इसलिए मैं किसी भी तरह से चयनकर्ता धागा चयन कुंजी पर गतिविधि हर समय कुछ संग्रह/चर की जांच नहीं करेगा। – Nilesh