一次线程被挂起问题排查
背景
有个线程池,大概长这样:
ThreadPoolExecutor executor = new ThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>(1000),new ThreadPoolExecutor.CallerRunsPolicy());
一开始运行的好好的,后面怎么提交任务都没有反应。
排查
首先推测是任务执行太慢之类的问题给阻塞住了
检查了下调用方代码,大概只有两种:
A方法
executor.execute(() -> do http request)
B方法
executor.execute(() -> A方法)
一开始感觉B方法看着很有问题,甚至还看了下线程池调度流程,发现完全没问题,
查看了日志也没有什么相关的报错。
程序上没线索就只能看下线程状态了
使用jstate
工具定位到问题线程
发现它一直都卡在了java.net.SocketInputStream.socketRead0
具体线程调用栈如下:
Thread xxx: (state = IN_NATIVE)- java.net.SocketInputStream.socketRead0(java.io.FileDescriptor, byte[], int, int, int) @bci=0 (Compiled frame; information may be imprecise)- java.net.SocketInputStream.socketRead(java.io.FileDescriptor, byte[], int, int, int) @bci=8, line=116 (Compiled frame)- java.net.SocketInputStream.read(byte[], int, int, int) @bci=117, line=171 (Compiled frame)- java.net.SocketInputStream.read(byte[], int, int) @bci=11, line=141 (Compiled frame)- sun.security.ssl.SSLSocketInputRecord.read(java.io.InputStream, byte[], int, int) @bci=4, line=466 (Compiled frame)- sun.security.ssl.SSLSocketInputRecord.readHeader() @bci=31, line=460 (Compiled frame)- sun.security.ssl.SSLSocketInputRecord.decode(java.nio.ByteBuffer[], int, int) @bci=10, line=159 (Compiled frame)- sun.security.ssl.SSLTransport.decode(sun.security.ssl.TransportContext, java.nio.ByteBuffer[], int, int, java.nio.ByteBuffer[], int, int) @bci=10, line=110 (Compiled frame)- sun.security.ssl.SSLSocketImpl.decode(java.nio.ByteBuffer) @bci=14, line=1198 (Compiled frame)- sun.security.ssl.SSLSocketImpl.readHandshakeRecord() @bci=12, line=1107 (Compiled frame)- sun.security.ssl.SSLSocketImpl.startHandshake(boolean) @bci=122, line=400 (Compiled frame)- sun.security.ssl.SSLSocketImpl.startHandshake() @bci=2, line=372 (Compiled frame)- sun.net.www.protocol.https.HttpsClient.afterConnect() @bci=254, line=587 (Interpreted frame)- sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect() @bci=51, line=185 (Interpreted frame)- sun.net.www.protocol.https.HttpsURLConnectionImpl.connect() @bci=4, line=167 (Interpreted frame)- org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(org.springframework.http.HttpHeaders, byte[]) @bci=61, line=76 (Interpreted frame)- org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(org.springframework.http.HttpHeaders) @bci=27, line=48 (Interpreted frame)- org.springframework.http.client.AbstractClientHttpRequest.execute() @bci=9, line=53 (Interpreted frame)- org.springframework.web.client.RestTemplate.doExecute(java.net.URI, org.springframework.http.HttpMethod, org.springframework.web.client.RequestCallback, org.springframework.web.client.ResponseExtractor) @bci=37, line=742 (Interpreted frame)- org.springframework.web.client.RestTemplate.execute(java.lang.String, org.springframework.http.HttpMethod, org.springframework.web.client.RequestCallback, org.springframework.web.client.ResponseExtractor, java.lang.Object[]) @bci=21, line=677 (Compiled frame)- org.springframework.web.client.RestTemplate.exchange(java.lang.String, org.springframework.http.HttpMethod, org.springframework.http.HttpEntity, java.lang.Class, java.lang.Object[]) @bci=26, line=586 (Compiled frame)- java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor$Worker) @bci=95, line=1149 (Interpreted frame)
查资料分析了Oracle官网有提交过bug记录:
这篇没看懂…
https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8075484
https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8233660
看了下我的jdk版本:8u261
emmm…重…重启大法…
后续
一段时间后问题还是出现了…
我回头有研读了一遍调用链路
发现RestTemplate默认创建的请求工厂SimpleClientHttpRequestFactory默认超时时间是无限制的
导致构建出的SimpleBufferingClientHttpRequest对象在建立Socket通道时无限阻塞了
一次线程被挂起问题排查相关推荐
- 线程的挂起是错误的概念实际是线程的阻塞,挂起只针对进程,将进程挂起会将进程从内存空间交换到磁盘空间的过程
线程的挂起是错误的概念实际是线程的阻塞 线程的主要状态有运行态,就绪态和阻塞态.挂起态对线程没有什么意义,这是由于此类状态是一个进程级的概念.特别地,如果一个进程被换出,由于它的所有线程都该进程的地址 ...
- 树莓派cpu检测_【树莓派3B+测评】线程的挂起与恢复CPU温度检测
[树莓派3B+测评]线程的挂起与恢复&CPU温度检测 [复制链接] 本帖最后由 donatello1996 于 2018-12-22 17:33 编辑 在TCP通信中,除了线程的创建和删除以外 ...
- Java线程的挂起与恢复 wait(), notify()方法介绍
一, 什么是线程的挂起与恢复 从字面理解也很简单. 所谓线程挂起就是指暂停线程的执行(阻塞状态). 而恢复时就是让暂停的线程得以继续执行.(返回就绪状态) 二, 为何需要挂起和恢复线程. 我们来看1个 ...
- java怎么看具体被挂起的线程_Java线程的挂起、恢复和终止
有时,线程的挂起是很有用的.例如,一个独立的线程可以用来显示当日的时间.如果用户不希望用时钟,线程被挂起.在任何情形下,挂起线程是很简单的,一旦挂起,重新启动线程也是一件简单的事. 挂起,终止和恢复线 ...
- 七. 多线程编程11.线程的挂起、恢复和终止
有时,线程的挂起是很有用的.例如,一个独立的线程可以用来显示当日的时间.如果用户不希望用时钟,线程被挂起.在任何情形下,挂起线程是很简单的,一旦挂起,重新启动线程也是一件简单的事. 挂起,终止和恢复线 ...
- java怎么看具体被挂起的线程_Java知多少(65)线程的挂起、恢复和终止
有时,线程的挂起是很有用的.例如,一个独立的线程可以用来显示当日的时间.如果用户不希望用时钟,线程被挂起.在任何情形下,挂起线程是很简单的,一旦挂起,重新启动线程也是一件简单的事. 挂起,终止和恢复线 ...
- 线程的挂起(suspend)和继续执行(resume)是什么情况?
前言 本文隶属于专栏<100个问题搞定Java并发>,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见100个问题搞定Java并发 ...
- 关于Qt中线程的挂起和唤醒问题
为了平台的可移植性,现在好多公司或开发者都在用Qt开发,但是Qt开发文档有一个不非常理想的问题是,有些问题描述的不是太详细,特别是涉及到线程的挂起,唤醒.和sleep()等问题. 在Qt开发中,有许多 ...
- java线程挂起唤醒_java线程技术6_线程的挂起和唤醒[转]
转自:http://blog.chinaunix.net/uid-122937-id-215913.html 1. 线程的挂起和唤醒 挂起实际上是让线程进入"非可执行"状态下,在这 ...
最新文章
- python读中文文本_python读取中文txt文本
- WCF中常见的几种Host,承载WCF服务的方法详解
- Cloudify — OpenStack Infrastructure Plugin V3
- innodb行锁理解
- 安装python遇到错误_安装Python时遇到如下问题,解决方案
- java 二维数组对角线_二维数组(矩阵)对角线输出
- BigDecimal 常用方法
- 这个黑科技耳机方便又时尚,听歌也不怕坐过
- iOS:重识Transform和frame
- 合振动的初相位推导_如何理解单自由度系统振动
- 31省农村居民人均可支配收入 (2002-2018年)
- 华为鸿蒙deveco studio编译时提示Browserslist: caniuse-lite is outdated的解决办法
- ele饿了么表单验证的校验提示突破v-if的限制
- 验证集与测试集的区别
- Windows 9X电脑经常出现bluescreen蓝屏怎么办?
- 百度地图商家标注,查询附近3000米内的商家并标到地图上
- DICOM协议学习笔记(二)
- Unity (一) 下载与安装
- 更改tomcat访问端口()
- Python 通过URL打开图片
热门文章
- Scroll Segmented Control(Swift)
- 探讨如何利用C#登录QQ邮箱进行群邮件的发送
- 未处理System.Runtime.InteropServices.COMException Message=The specified path is invalid
- 如何设计一个中介录入房源信息平台所需关键内容
- Android 覆盖安装失败
- php ajaxfileupload.js 使用,使用ajaxfileupload.js实现上传文件功能
- maven学习(2):依赖
- ubuntu 安裝deb_.deb文件如何安装,Ubuntu下deb安装方法图文详解
- 路径中使用斜杠/和反斜杠\的区别
- ④绝一首--雨过文字舞