سؤال

يرجى توجيه / قدم لي مثال عمل ل selector.wakeup(); طريقة بين اثنين من المواضيع.

حاولت إنشاء برنامج بسيط حيث يوجد موضوع ينتظر طريقة Selector.Section (). يخلق الخيط الثاني بعض المقابس ويحاول التسجيل مع محدد؛ التي يتم حظر الموضوع الأول.

وبالتالي أنا بحاجة إلى استخدام محدد wakeup الطريقة، ولكن بطريقة ما لم يخرج مؤشر الترابط الأول من وضع الحظر.

تنص Javadoc من طريقة الاستيقاظ:

إذا تم حظر مؤشر ترابط آخر في حالة من الاحتجاج من الأساليب () أو المحللة.

ملاحظة: هناك عدد قليل من العمل حول العمل؛ واحد منهم هو اختيار (مهلة) ولكن أحاول معرفة مكان الخطأ هو.

رمز PSuDo:

خيط الأول:

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

}
هل كانت مفيدة؟

المحلول

ربما لا ترغب في حظر المقبس من الخيط 2، إذا تم حظره إذا كنت تقوم بتسجيله في محدد (كمقصود المحددين لمخالد I / O). أعتقد أنه من الممارسات الشائعة أيضا السماح للمحدد باستخدام الاتصال مع OP_CONNECT (باستخدام Socketchannel.finishConnection ()).

يبدو أنه يمكن أن يكون لديك حالة سباق محتملة هنا. تخيل هذه السلسلة من الأحداث:

  1. الموضوع 1: Selector.Section ()
  2. ... الوقت يمضي ...
  3. الموضوع 2: Thread1.selector.wakeup ()
  4. الموضوع 1: الشيكات مفاتيح القبول
  5. الموضوع 1: الشيكات مفاتيح للكموضة
  6. الموضوع 1: حلقة
  7. الموضوع 1: Selector.Section ()
  8. الموضوع 2: حاول التسجيل في المحدد (ولكن بعد فوات الأوان لذلك حدد ())

أود أن أقترح وجود مؤشر ترابط 2 إعداد Socketchannel، خبأه بعيدا في مكان ما، يمكن أن تحصل عليه موضوع واحد (تأكد من أن تكون مؤكدا من الخيط آمنا عند القيام بذلك)، ثم استيقظ المحدد، واسمحوا بذلك التحقق من المفاتيح الموجودة في موضوع 1 ولديه الموضوع 1 تسجيل Socketchannel الجديد قبل أن يطلق عليه Selector.Select () مرة أخرى.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top