欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于AsynchronousSocketChannel的正确关闭方法,以及关闭出错异常AsynchronousCloseException的处理

程序员文章站 2022-05-29 16:29:37
...
如下异常一致困扰了我很久,Google和度娘了很久都没有解决,突然某天脑子抽风,就想到了如下
java.nio.channels.AsynchronousCloseException
at sun.nio.ch.UnixAsynchronousSocketChannelImpl.finishRead(UnixAsynchronousSocketChannelImpl.java:408) ~[?:1.8.0_45]
at sun.nio.ch.UnixAsynchronousSocketChannelImpl.finish(UnixAsynchronousSocketChannelImpl.java:191) ~[?:1.8.0_45]
at sun.nio.ch.UnixAsynchronousSocketChannelImpl.implClose(UnixAsynchronousSocketChannelImpl.java:225) ~[?:1.8.0_45]
at sun.nio.ch.AsynchronousSocketChannelImpl.close(AsynchronousSocketChannelImpl.java:144) ~[?:1.8.0_45]


出现这个异常的原因其实就是正在从channel读取数据,Input还在走,所以直接close掉是不行的
但是,按照Google的某些描述,进行如下操作
channel.shutdownInput();
channel.shutdownOutput();
channel.close();
其实依然会有这个异常的抛出,后来某天突然想到,这个Channel本身就是异步的,那么shutdown是不是也是异步处理的,也就是shutdown完之后,还没有真正的shutdown掉就执行了close,这样的话,就和之前的不执行shutdown没什么区别了
于是,就在执行者三条语句的时候,异步的分别执行了,执行完第一个,起一个线程执行第二个,执行完第二个起一个线程执行第三个


因为之前分析得出,其实再执行shutdownInput的操作之后,在跳出这个方法栈之后,Read的监听事件还会做一次响应,这个时候的CompletionHandler接口的实现方法completed的第一个参数result值是小于0的,所以执行完这个之后,才应该算彻底的shutdown掉了,然后就可以执行close的方法了