线程hang住了?
每天总结一个小知识点,工作小记第2回;
今天同事问我,他的代码里,有好几个线程被hang住了,一直处于RUNNABLE,调用BufferedReader.readLine不返回,想要加个管理线程,管理这些被hang住的线程;调用了hang住线程的Thread.interrupt(),但是不起作用;
我的理解也不是特别深刻,用我自己的白话来讲:
1. 调用Thread.interrupt()是需要被调用线程自己做中断处理的,外部只是一个触发者,但是目前线程被readLine的IO阻塞,是没有机会去执行中断处理的。
2.中断处理的响应是建立在被中断线程实现了中断处理的基础上,如果对方没认真处理中断操作,或者直接暴力try catch,什么也不会发生。
如果在不改变readLine的操作的基础上,让线程恢复回来,就调用相关IO的close方法,强制把IO流关闭,引发IOException,就能恢复。以如下代码为例:
1 2 3 4 5 | Socket socket = new Socket(ADDRESS, PORT); InputStream is = socket.getInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); System.out.println( "receive: " + br.readLine()); |
关闭socket是可以的;关闭is也是可以的,关闭is本质上是关闭SocketInputStream子类,关闭的也是绑定的Socket,效果一样。
关闭isr和br是不可以的。如果调用了isr和br的close方法,那么调用者的线程也会被hang住。因为调用br的close会去调用内部的isr的close,这个close方法有加锁。
InputStreamReader 继承了Reader类,拥有一个lock锁,在调用readLine的时候,已经锁定了lock,此时外部线程调用close方法,会被锁住,导致自己也被hang住。导致 葫芦娃救爷爷,一个一个送。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异