جافا نيو، والتحقق مما إذا كانت القناة جاهزة للقراءة والكتابة
سؤال
بدلا من استخدام محدد بالطريقة المعتادة، حيث يمكن تحديد رسالة من كل قناة جاهزة وإرسالها، أود اختيار أي اتصال جاهز حاليا وإرسال رسالة هناك.
من المفترض أن يتم ذلك من خلال إلقاء جميع القنوات في محدد لقراءةهم وتمييزهم جاهزين للقراءة إذا خرجوا، ثم القيام بنفس الشيء في الكتابة، ثم يختارون من بين أولئك الذين قمت بتمييزهم.
هل هذه فكرة جيدة، هل هناك طريقة أفضل للقيام بذلك، وماذا يجب أن أشاهدها؟ على سبيل المثال، روكس التعليمي تنص على "إذا حاولت مزج القراءة المرجعية، فاكتب OP، فستحصل بسرعة على مشكلة. تم عرض تطبيق Sun Windows Deadlock إذا قمت بذلك." هل هناك مشابه gotchas هنا؟ ما هي أفضل طريقة لتنفيذ:
boolean isReadyForRead(SocketChannel c);
boolean isReadyForWrite(SocketChannel c);
المحلول
ماذا عن شيء مثل هذا؟
public static boolean isReadyForRead(SocketChannel socket) throws IOException {
return isReady(socket, SelectionKey.OP_READ);
}
public static boolean isReadyForWrite(SocketChannel socket) throws IOException {
return isReady(socket, SelectionKey.OP_WRITE);
}
public static boolean isReady(SocketChannel socket, int op) throws IOException {
// Setup
if (socket.isBlocking())
throw new IllegalArgumentException("Socket must be in non-blocking mode");
Selector selector = SelectorProvider.provider().openSelector();
socket.register(selector, op);
// Real work
if (selector.selectNow() == 0)
return false;
// Just in case selector has other keys
return selector.selectedKeys().contains(socket.keyFor(selector));
}
هذه المكالمة غير فعالة بشكل رهيب لأنها تقوم بالإعداد في كل مرة. إذا كان لديك فئة مغلفة، فيجب نقل ذلك. إذا كنت تعرف المحدد يحتوي فقط على مفتاح واحد، فيمكن تغيير السطر الأخير إلى "return true;
".
أنا فقط أفعل هذا للمتعة. لا أستطيع التفكير في سيناريو أن هذا سيكون مفيدا. حدد () مصمم لإخبارك بحالة المقابس بكفاءة ويجب أن يستخدم الجميع هذا مباشرة.
نصائح أخرى
يجب أن تستخدم موكتك الخاص بك للتحقق إذا كان المقبس جاهزا للقراءة أو الكتابة، عندما يستيقظ المحدد.
هنا جدا برنامج تعليمي مفيد على كتابة خادم Nio والعميل http://rox-xmlrpc.sourceforge.net/niotut/