庄周梦蝶

生活、程序、未来
   :: 首页 ::  ::  :: 聚合  :: 管理

NIO的SelectableChannel关闭的一个问题

Posted on 2008-06-18 01:50 dennis 阅读(2449) 评论(2)  编辑  收藏 所属分类: java
    SocketChannel和ServerSocketChannel,两者的父类是SelectableChannel,它在jdk中的文档有这么段话:

    Once registered with a selector, a channel remains registered until it is deregistered.This involves deallocating whatever resources were allocated to the channel by the selector.
    A channel cannot be deregistered directly; instead, the key representing its registration must be cancelled. Cancelling a key requests that the channel be deregistered during the selector's next selection operation.

    也就是说关闭一个已经注册的SelectableChannel需要两个步骤:

1)取消注册的key,这个可以通过SelectionKey.cancel方法,也可以通过SelectableChannel.close方法,或者中断阻塞在该channel上的IO操作的线程来做到。

2)后续的Selector.selectXXX方法的调用才真正地关闭本地Socket。

    因而,如果,如果在取消SelectionKey后没有调用到selector的select方法(因为Client一般在取消key后, 我们都会终止调用select的循环,当然,server关闭一个注册的channel我们是不会终止select循环的),那么本地socket将进入CLOSE-WAIT状态(等待本地Socket关闭)。简单的解决办法是在 SelectableChannel.close方法之后调用Selector.selectNow方法,类似:

   Selector sel;
   SocketChannel sch;
   // …
   sch.close();
   sel.selectNow();


    Nio编程有很多这样细节性的东西需要注意,通常情况下还是利用成熟的框架为妙。


评论

# re: NIO的SelectableChannel关闭的一个问题  回复  更多评论   

2008-06-18 09:19 by Arbow
这样的分享不错!“通常情况下还是利用成熟的框架为妙”

# re: NIO的SelectableChannel关闭的一个问题  回复  更多评论   

2009-07-13 18:11 by 吴冬冬
感谢
为这个问题烦恼了好几天了
我用close关闭的select 怎么也关闭不了

只有注册用户登录后才能发表评论。


网站导航: