NIO的SelectableChannel关闭的一个问题
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编程有很多这样细节性的东西需要注意,通常情况下还是利用成熟的框架为妙。
上一篇: 工作的几个tip
下一篇: SpringMVC运行原理(流程图)
推荐阅读
-
基于C# 中可以new一个接口?的问题分析
-
一个单引号引发的MYSQL性能问题分析
-
mysql 一个较特殊的问题:You can't specify target table 'wms_cabinet_form'
-
基于C# 中可以new一个接口?的问题分析
-
一个单引号引发的MYSQL性能问题分析
-
SQL order by ID desc/asc加一个排序的字段解决查询慢问题
-
mysql 一个较特殊的问题:You can't specify target table 'wms_cabinet_form'
-
PHP浮点数的一个常见问题
-
Linq to SQL 插入数据时的一个问题
-
Win10突然跳出提示网络发现已关闭问题的解决方法