背景

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

      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. python读中文文本_python读取中文txt文本
  2. WCF中常见的几种Host,承载WCF服务的方法详解
  3. Cloudify — OpenStack Infrastructure Plugin V3
  4. innodb行锁理解
  5. 安装python遇到错误_安装Python时遇到如下问题,解决方案
  6. java 二维数组对角线_二维数组(矩阵)对角线输出
  7. BigDecimal 常用方法
  8. 这个黑科技耳机方便又时尚,听歌也不怕坐过
  9. iOS:重识Transform和frame
  10. 合振动的初相位推导_如何理解单自由度系统振动
  11. 31省农村居民人均可支配收入 (2002-2018年)
  12. 华为鸿蒙deveco studio编译时提示Browserslist: caniuse-lite is outdated的解决办法
  13. ele饿了么表单验证的校验提示突破v-if的限制
  14. 验证集与测试集的区别
  15. Windows 9X电脑经常出现bluescreen蓝屏怎么办?
  16. 百度地图商家标注,查询附近3000米内的商家并标到地图上
  17. DICOM协议学习笔记(二)
  18. Unity (一) 下载与安装
  19. 更改tomcat访问端口()
  20. Python 通过URL打开图片

热门文章

  1. Scroll Segmented Control(Swift)
  2. 探讨如何利用C#登录QQ邮箱进行群邮件的发送
  3. 未处理System.Runtime.InteropServices.COMException Message=The specified path is invalid
  4. 如何设计一个中介录入房源信息平台所需关键内容
  5. Android 覆盖安装失败
  6. php ajaxfileupload.js 使用,使用ajaxfileupload.js实现上传文件功能
  7. maven学习(2):依赖
  8. ubuntu 安裝deb_.deb文件如何安装,Ubuntu下deb安装方法图文详解
  9. 路径中使用斜杠/和反斜杠\的区别
  10. ④绝一首--雨过文字舞