貌似SelectionKey.cancel只对下一次的Selector.cancel()有效,代码如下,只贴了简要的:
nKeys = selector.select();
ExecutorService exec = Executors.newFixedThreadPool(10);
if (nKeys > 0)
{
Set selectedKeys = selector.selectedKeys();
Iterator it = selectedKeys.iterator();
while (it.hasNext())
{
SelectionKey selectionKey = (SelectionKey) it.next();
it.remove();
if (selectionKey.isAcceptable())
{
。。。 //省略了accept()通道的注册代码
}
else if(selectionKey.isReadable())
{
exec.execute(new ProcessThread(selectionKey)); //如果客户端数据没有处理完整,将会重新注册该key
selectionKey.cancel();
}
}
}
客户端只连了一次,在ProcessThread(selectionKey).run的处理过程中,select()还有两次成功返回,第一次返回时nKeys=0,第二次nKey=1。如果使用单步调试,也就是在exec.execute(new ProcessThread(selectionKey))和下一次select()之间有足够的时间处理通道的数据,则select()将阻塞。
不太明白为什么selectionKey.cancel()不起作用。