有人说java nio在多线程环境下编程简直就是个恶梦,其实你如果能把握住java nio API的要领,你就可以将之驾驭.
0. 一个 channal 对应一个SelectionKey in the same selector.
e.g:
SelectionKey sk=sc.register(selector, SelectionKey.OP_READ, handler);
sk==sc.register(selector, SelectionKey.OP_WRITE, handler) true?
selector.select() 每次返回的对同一channal的sk是否相同?
1.channel.register(...) may block if invoked concurrently with another registration[another.register(...)] or selection operation[selector.select(...)] involving *****the same selector*****.
这个是register方法jdk src上的原文,
e.g:
如果一个selection thread已经在select方法上等待ing,那么这个时候如果有另一条线程调用channal.register方法的话,那么它将被blocking.
2.selectionKey.cancel() : The key will be removed from all of the selector's key sets during *****the next selection operation[selector.select(...)]*****.
may block briefly if invoked concurrently with a cancellation[cancel()] or selection operation[select(...)] involving ***the same selector***.
这个也是cancel方法jdk src上的原文,
e.g:
你先将一个selectionKey.cancel(),然后随即再channel.register to the same selector,
在cancel和register之间,如果没有线程(包括当前线程)进行select操作的话,
那么 throws java.nio.channels.CancelledKeyException.
所以 cancel-->select-->re-register.
3.if don't remove the current selectedKey from selector.selectedKeys()[Set] 将导致 selector.select(...) not block [may be cpu 100%,specially when client cut the current channel(connection)].
e.g:
Iterator it=selector.selectedKeys().iterator();
...for/while it.hasNext()...
it.remove();
if remove the current selectedKey from selector.selectedKeys()[Set] but don't sk.interestOps(sk.interestOps()& (~sk.readyOps()));将导致 selector.select(...) not block [select() not block several times, or excepted exception]
4.op_write should not be registered to the selector. &nbs