背景

有个线程池,大概长这样:

      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通道时无限阻塞了

一次线程被挂起问题排查相关推荐

  1. 线程的挂起是错误的概念实际是线程的阻塞,挂起只针对进程,将进程挂起会将进程从内存空间交换到磁盘空间的过程

    线程的挂起是错误的概念实际是线程的阻塞 线程的主要状态有运行态,就绪态和阻塞态.挂起态对线程没有什么意义,这是由于此类状态是一个进程级的概念.特别地,如果一个进程被换出,由于它的所有线程都该进程的地址 ...

  2. 树莓派cpu检测_【树莓派3B+测评】线程的挂起与恢复CPU温度检测

    [树莓派3B+测评]线程的挂起与恢复&CPU温度检测 [复制链接] 本帖最后由 donatello1996 于 2018-12-22 17:33 编辑 在TCP通信中,除了线程的创建和删除以外 ...

  3. Java线程的挂起与恢复 wait(), notify()方法介绍

    一, 什么是线程的挂起与恢复 从字面理解也很简单. 所谓线程挂起就是指暂停线程的执行(阻塞状态). 而恢复时就是让暂停的线程得以继续执行.(返回就绪状态) 二, 为何需要挂起和恢复线程. 我们来看1个 ...

  4. java怎么看具体被挂起的线程_Java线程的挂起、恢复和终止

    有时,线程的挂起是很有用的.例如,一个独立的线程可以用来显示当日的时间.如果用户不希望用时钟,线程被挂起.在任何情形下,挂起线程是很简单的,一旦挂起,重新启动线程也是一件简单的事. 挂起,终止和恢复线 ...

  5. 七. 多线程编程11.线程的挂起、恢复和终止

    有时,线程的挂起是很有用的.例如,一个独立的线程可以用来显示当日的时间.如果用户不希望用时钟,线程被挂起.在任何情形下,挂起线程是很简单的,一旦挂起,重新启动线程也是一件简单的事. 挂起,终止和恢复线 ...

  6. java怎么看具体被挂起的线程_Java知多少(65)线程的挂起、恢复和终止

    有时,线程的挂起是很有用的.例如,一个独立的线程可以用来显示当日的时间.如果用户不希望用时钟,线程被挂起.在任何情形下,挂起线程是很简单的,一旦挂起,重新启动线程也是一件简单的事. 挂起,终止和恢复线 ...

  7. 线程的挂起(suspend)和继续执行(resume)是什么情况?

    前言 本文隶属于专栏<100个问题搞定Java并发>,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见100个问题搞定Java并发 ...

  8. 关于Qt中线程的挂起和唤醒问题

    为了平台的可移植性,现在好多公司或开发者都在用Qt开发,但是Qt开发文档有一个不非常理想的问题是,有些问题描述的不是太详细,特别是涉及到线程的挂起,唤醒.和sleep()等问题. 在Qt开发中,有许多 ...

  9. java线程挂起唤醒_java线程技术6_线程的挂起和唤醒[转]

    转自:http://blog.chinaunix.net/uid-122937-id-215913.html 1. 线程的挂起和唤醒 挂起实际上是让线程进入"非可执行"状态下,在这 ...

最新文章

  1. 机器学习中的聚类算法(2):Mean Shift算法
  2. docker 的mysql镜像使用手册 官网原文 日期2017-05-25
  3. python 访问需要HTTP Basic Authentication认证的资源
  4. WannaCry病毒横行Windows,Mac用户不应幸灾乐祸!
  5. 设计模式在项目中的应用案例_项目化学习案例(五):菊花种植的秘密——项目化学习在菊种植课程中的应用设计案例...
  6. 双向关联一对一映射详解(1)
  7. 转: MATLAB: cat函数使用
  8. NSA和CISA 联合发布Kubernetes 安全加固指南
  9. 数据存储-传输-分析
  10. 【深度优先搜索】网格类问题:牛客网:机器人的运动范围
  11. 函数的调用过程——栈帧。
  12. Windows网络编程之send()函数
  13. 基于SSM车牌识别停车场管理系统
  14. python创建txt文件换行输入,python如何创建txt文件并写入
  15. 基于阿里云的系统灾备方法架构与安全应急预案介绍
  16. 用四叉树加速碰撞检测
  17. [任务2]安装ubuntu Linux
  18. 特立独行的幸福(25分)Python
  19. 计算机考研需要过英语六级吗,研究生毕业要过英语六级吗 研究生毕业对英语六级有要求吗...
  20. 基于Java实现一个简单的记事本Android App

热门文章

  1. 正向全局代理(proxy_pool + Proxifier 4.01)
  2. Revit开发 - 墙的移动,复制,旋转,镜像
  3. 【UML】--对象图
  4. C# 操作CAD报错【COMException (0x8001010A)消息筛选器显示应用程序正在使用中】的一种处理方式
  5. Mac系统home目录无法创建文件最全解决方法
  6. 「手机秒变照片传送门!使用 Flask 打造你的个人云相册!」
  7. 2022年2月云主机性能评测报告
  8. 大连海事大学与重邮计算机,中国最低调的10所大学, 有实力不张扬, 实力确很强!...
  9. CSS的各种属性,以及样式设置
  10. CSDN写博客基本技巧