关于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的方法了
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的方法了
下一篇: 常用的ETL工具