java nio在多线程环境下的恶梦之终结

有人说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<SelectionKey> it=selector.selectedKeys().iterator();

...for/while it.hasNext()...
it.remove();<------*****must do it. or Keys' Set.clear() finally;

 

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.   [may be cpu100%]

 

5. if involving  wakeup() before select() [wakeup called several times >=1],the next select() not block [not block just once].

 

尽管以前有些人分析了nio的wakeup性能及not block in linux的bug,但是java nio依然是高效的,那些c/c++的牛人们应该去关注一下jre/bin目录下的nio.dll[windows上的jdk1.6还没有使用IOCP] , ./jdk/jre/lib/amd64/libnio.so[linux上的jdk1.6已经使用epoll了].

基于java nio的服务器:mina,xSocket,girzzly[glassfish],jetty(基于girzzly),tomcat6[可以配置Http11NioProtocol]...其中从本人对girzzly,tomcat6的源码分析来看,它们都还没有真正发挥出nio异步处理请求的优点,它们的读写还都是blocking的虽然使用了selectorPool,此外tomcat6要剥离出socket通信还要花费一定的功夫.而mina,xSocket却是符其实.

 

 

 

 

你可能感兴趣的:(java,jdk,多线程,linux,Mina)