java nio 捕获异常_java nio channel抛出ClosedByInterruptException的情况
java nio里的channel是实现自InterruptibleChannel接口的,这个接口的注释里有说明,当正在操作这个channel的线程被其他线程中断,则会close这个channel,当前(被中断的)线程抛出一个ClosedByInterruptException异常。
我们今天在排查一个问题时,用户线程执行了下面的调用过程(从上往下):
org.apache.catalina.connector.CoyoteOutputStream.flush ---》
org.apache.tomcat.util.net.NioChannel.write ---》
sun.nio.ch.SocketChannelImpl.write ---》
java.nio.channels.spi.AbstractInterruptibleChannel.end // 这里抛出异常
来看一下这个sun.nio.ch.SocketChannelImpl.write 方法内部,它的详细代码可以看这里) 这里简化一些:
public int write(ByteBuffer buf) throws IOException {
...
synchronized (writeLock) {
...
try {
begin();
...
} finally {
...
end(n > 0 || (n == IOStatus.UNAVAILABLE));
...
}
}
}
主要看一下它里面的begin和end,先看end方法,异常抛出的地方:
protected final void end(boolean completed)
throws AsynchronousCloseException
{
blockedOn(null);
Thread interrupted = this.interrupted;
if (interrupted != null && interrupted == Thread.currentThread()) {
interrupted = null;
throw new ClosedByInterruptException();
}
if (!completed && !open)
throw new AsynchronousCloseException();
}
可以看到ClosedByInterruptException异常抛出的前提是当前线程被标记为已中断的;而这个判断是在begin方法里做的:
protected final void begin() {
if (interruptor == null) {
interruptor = new Interruptible() {
public void interrupt(Thread target) {
synchronized (closeLock) {
if (!open)
return;
open = false;
interrupted = target;
try {
AbstractInterruptibleChannel.this.implCloseChannel();
} catch (IOException x) { }
}
}};
}
blockedOn(interruptor);
Thread me = Thread.currentThread();
if (me.isInterrupted()) // 检测当前线程是否已中断
interruptor.interrupt(me);
}
在begin方法里,检查当前线程如果是中断状态,用引用记录起来(为了后边比较使用),并关闭了channel。
现在用scala模拟一下这个异常:
$ cat server
import java.nio._
import java.net._
import java.nio.channels._
val serverSock = ServerSocketChannel.open()
serverSock.socket().bind(new InetSocketAddress(54321))
val ch:SocketChannel = serverSock.accept()
println("ok,received")
Thread.currentThread().interrupt() //中断当前线程
try{
ch.socket().getOutputStream().write(200)
}catch{
case e:Throwable => println(e)
}
上面的这段脚本,用nio模拟了一个server等待客户端的链接,当链接过来的时候,中断当前线程,然后继续channel进行处理的时候会捕获到ClosedByInterruptException异常。
启动上面的脚本
$ scala server
在另一个终端下模拟一次client请求:
$ telnet localhost 54321
这时会看到server端的输出信息:
$ scala server
ok,received
java.nio.channels.ClosedByInterruptException
java nio 捕获异常_java nio channel抛出ClosedByInterruptException的情况相关推荐
- java 是否继续_Java异常被抛出或被捕获之后,代码是否继续执行的问题
在写程序的时候,我们经常被教导,要对异常的信息进行处理,哪里该抛出异常.但是,更多的时候,我们只是模仿异常的抛出,却不知道为什么要这样抛异常(被catch了?被向上抛了?后面的代码是否执行了?). 接 ...
- java 在方法中抛出异常_Java异常的抛出
在Java中,当定义的方法可能产生异常时,程序员必须抛出可能的异常. 抛出异常的两种方式,一是在方法内部用throw语句,二是在方法定义时用throws关键字 1.throw语句 在Java中,thr ...
- java搭云梯_java nio为什么是通道(一):通往nio的云梯
java nio的通道是一个全新的I/O实现,没有扩展或者继承其它的类或者包. 通过只能在字节缓冲区上操作,因此Channel是面向字节的接口,为什么要这样设计呢?主要是因为通道直接会和操作系统的I/ ...
- java nio多路复用_Java NIO系列教程(六) 多路复用器Selector
多路复用器Selector是Java NIO编程的基础,熟练地掌握Selector对于掌握NIO编程至关重要.多路复用器提供选择已经就绪的任务的能力.简单来讲,Selector会不断地轮询注册在其上的 ...
- Java nio 异常_java.nio.BufferOverflowException 异常问题
系统运行一段时间,tomcat就会一直抛出下面的异常,造成系统不能访问,是什么原因? 2018-11-30 10:20:43,014 org.nutz.mvc.impl.processor.FailP ...
- java 向上抛异常_java throws 向上抛出的概念问题
展开全部 ------------------附注------------------------ 向上抛出的意思 针对 子类 父类, 这里面涉及到几个方面,最重323131333532363134 ...
- java nio 事件_Java NIO原理及实例
Java NIO是在jdk1.4开始使用的,它既可以说成"新I/O",也可以说成非阻塞式I/O.下面是java NIO的工作原理: 1. 由一个专门的线程来处理所有的 IO 事件, ...
- java bytebuffer 读写_java nio bytebuffer文件读写问题
为什么下面的代码从文件中读不出3和2来?importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOExc ...
- java nio 详_java nio详解
一. 分布式rpc框架有很多,比如dubbo,netty,还有很多其他的产品.但他们大部分都是基于nio的, nio是非阻塞的io,那么它的内部机制是怎么实现的呢. 1.由一个专门的线程处理所有IO事 ...
- java 最后的异常_java – 最后不要抛出堆栈溢出异常
Error不是例外.所以捕捉任何异常都不会捕获StackOverflowError. 所以让我们先来看一下"明显的错误" – (这段代码不太适合这个答案后面的说明): catch( ...
最新文章
- BaseTDI.sys 瑞星卡巴冲突,导致机器蓝屏
- Python ATM
- 争论不休的TF 2.0与PyTorch,到底现在战局如何了? | 技术头条
- Java9新功能之HTTP2和REPL
- c字符串函数实现(1)---strncpy
- emwin edit控制的输入长度小数点怎么处理_变频器学习,变频器主电路与控制回路学习...
- Vertx JDBC 批处理
- 大数据之-Hadoop之HDFS的API操作_文件下载案例---大数据之hadoop工作笔记0058
- win32开发(绘制bitmap)
- UVA11192 Group Reverse【水题】
- 免费画图软件推荐 - draw.io
- Altium Designer 18生成Gerber教程
- 档案系列包括图书馆管理与服务器,基于Web的图书馆档案管理系统设计与实现.pdf...
- Ubuntu12.04软件安装指南
- 八核处理器真的比四核性能强悍吗?
- VB.NET 打开Excel文件,读取Excel内容,添加到DataGridView中并显示
- 学术会议日常英语交流_有效的日常会议的3个问题
- 封神台旧靶场-kali系列
- 机械行业如何实现多级经销订货在线化?试试数商云B2B电商系统
- python unescape函数_Python escape.url_unescape方法代碼示例
热门文章
- 计算机网络课程思政教学目标,计算机学院举行课程思政示范教学活动
- libtorrent源码分析(四)LSD实现
- matlab 如何查数据类型,MATLAB数据类型
- windows 如何录制电脑自身内部的声音,无需 (Stereo mix )立体声混合选项
- 两个命令行应用程序的交互——使用Java的Process类完成复杂控制台程序的自动化操作(以围棋GTP协议为例)
- 话费充值哪里便宜?这样充帮我省了不少钱,推荐给您
- python网页登录验证码_15.Python实现识别登录验证码(入门)
- 【数据结构】从零实现顺序表+链表相关操作
- Arduino ESP8266 AP Web 服务器示例程序
- HTTP协议-报文解析