SocketInputStream.socketRead0引起线程池提交任务后,futureTask.get超时

探讨线程池中futureTask.get超时影响及SocketInputStream.socketRead0导致的线程阻塞问题,分析核心线程被占用原因及解决策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 现象

线上发短信、邮箱验证码 的时候超时

在这里插入图片描述

2. 结论

  1. SocketInputStream.socketRead0导致线程阻塞,阻塞后占用了线程池的线程。多次阻塞后最终占用了全部的core线程。新提交的任务只能入队,没有线程来处理。
    由于 socket.read占用了corePoolSize 个 线程池的工作线程worker.thread , 这里一共有10个,全都阻塞了。

    而execute提交一个runnable的时候, 在达到corePoolSize后, 会将其放入workQueue中。直到workQueue满。

    新的任务只能入队(enQueue),不能被消费。

    所以 futureTask.get 一直超时。

  2. futureTask.get(timeout,timeunit)不会导致线程池的工作线程异常。工作线程会继续执行。

3. 相关代码

sendVcWorkerThreadPool是ThreadPoolExecutor的子类WorkerThreadPool
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
WorkerThreadPool
这里workQueue本身是一个优先队列,这里会无限扩容
ps:由于无限扩容, 这里maxinumPoolSize是无效的

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

先查找相关调用链的底层日志,发现根本没有调用底层方法。

而其他应用能调用到该底层,一直在输出日志,说明是execute本身有问题。

4. 查看堆栈:

搜索AsyncWorker(ps:自定义的线程池一定要重命名,找问题的时候方便),发现该线程池的10个core线程都处于runnable,且所有线程都在

sendEmail

在这里插入图片描述

5. 查看submitCall

虽然future.get有超时,但是这只能保证业务线程不阻塞。
future.get并不能打断线程池的线程。
在这里插入图片描述
这里的sendVcWorkerThreadPool#submitCall与ThreadPoolExecutor
ThreadPoolExecutor#submit类似
在这里插入图片描述
由于继承ThreadPoolExecutor,所以调用了ThreadPoolExecutor的execute
在这里插入图片描述

5.1 ThreadPoolExecutor#execute最终调用了 RunnableFuture#run方法

  • 调用链
    addWorker()->w.start()->treahd.run()->Worker.runWorker(Worker w)->task.run();

  • task即RunnableFuture ,newTaskFor创建了子类FutureTask

因此 查看FutureTask的run方法

  • FutureTask是对Callable的一层封装。

  • 超时只影响了业务线程(调用futureTask.get的线程),不影响工作线程。

5.2 从代码层面判断 futureTask.get超时只影响了业务线程(调用futureTask.get的线程),不影响工作线程。

FutureTask.run
在这里插入图片描述

运行完毕,设置结果
此时可以使用future.get出结果
在这里插入图片描述

这里让【因为future.get,调用park方法使得等待】的线程 恢复。
在这里插入图片描述

5.3 future.get

在这里插入图片描述

死循环检测是否完成, 超时后,直接return 当前state

Unsafe.park()本地方法休眠当前线程, HotSpot在Linux中中通过调用pthread_mutex_lock函数把线程交给系统内核进行阻塞。
在这里插入图片描述
休眠
在这里插入图片描述

检测的时候,先将当前线程添加到waitNode

在这里插入图片描述

5.3.1 测试future.get并不能打断线程池的线程。

在这里插入图片描述

6. 查看工作线程为何阻塞

虽然已经证明了futureTask.get超时后不会打断线程池的worker.thread,还是需要查看工作线程为何阻塞。
再回顾一下堆栈

在这里插入图片描述
execute的调用链是addWorker()->w.start()->treahd.run()->Worker.runWorker(Worker w)->task.run();
而FutureTask是对Callable的一层封装。

本身是SendEmailCall本身是一个Callable

我们只需要查看SendEmailCall的call方法为何一直在运行。

在这里插入图片描述
transport.connect
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

阻塞到readLine

在这里插入图片描述
到这里就很明显了, 是socket的inputStream调用read的时候阻塞。

在这里插入图片描述

socket是可以设置timeout的。

查找timeout的设置
在这里插入图片描述
getSocket
在这里插入图片描述

to为read超时时间,
cto为连接超时时间
如果不设置则都为永久

在这里插入图片描述

而创建的时候,没有设置timeout
到此就明白了, 设置timeout即可。
在这里插入图片描述

6.1 修复

props.put("mail.smtp.connectiontimeout", "3000");
props.put("mail.smtp.timeout", "3000");

在这里插入图片描述
在这里插入图片描述

debug测试
在这里插入图片描述

修改后

在这里插入图片描述

修改为超短时间 会报错。
在这里插入图片描述

7. 相关资料

线程池中的线程何时死亡?
SocketInputStream.socketRead0引起线程池提交任务后,futureTask.get超时
socket连接代理socketRead0(Native Method) 线程阻塞处理

java.net.SocketException: Connection reset at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:328) at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:355) at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:808) at java.base/java.net.Socket$SocketInputStream.read(Socket.java:966) at java.base/sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:484) at java.base/sun.security.ssl.SSLSocketInputRecord.readHeader(SSLSocketInputRecord.java:478) at java.base/sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:160) at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:111) at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1510) at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1425) at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:455) at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:426) at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:589) at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:187) at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1665) at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1589) at java.base/java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:529) at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:308) at com.intellij.util.io.HttpRequests.openConnection(HttpRequests.java:619) at com.intellij.util.io.HttpRequests$RequestImpl.getConnection(HttpRequests.java:361) at com.intellij.ide.plugins.marketplace.MarketplaceRequests$Companion.readOrUpdateFile$lambda$8(MarketplaceRequests.kt:185) at com.intellij.util.io.HttpRequests.doProcess(HttpRequests.java:524) at com.intellij.util.io.HttpRequests.process(HttpRequests.java:506) at com.intellij.util.io.HttpRequests$RequestBuilderImpl.connect(HttpRequests.java:335) at com.intellij.ide.plugins.marketplace.MarketplaceRequests$Companion.readOrUpdateFile(MarketplaceRequests.kt:182) at com.intellij.ide.plugins.marketplace.MarketplaceRequests.getMarketplacePlugins(MarketplaceRequests.kt:273) at com.intellij.openapi.updateSettings.impl.UpdateChecker.findUpdatesInJetBrainsRepository(UpdateChecker.kt:377) at com.intellij.openapi.updateSettings.impl.UpdateChecker.updateDescriptorsForInstalledPlugins$lambda$6(UpdateChecker.kt:239) at com.intellij.openapi.application.impl.ApplicationImpl$2.run(ApplicationImpl.java:249) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) at com.intellij.util.concurrency.ContextCallable.call(ContextCallable.java:32) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at com.intellij.util.concurrency.ContextRunnable.run(ContextRunnable.java:27) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:702) at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:699) at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1.run(Executors.java:699) at java.base/java.lang.Thread.run(Thread.java:840) 2025-05-27 10:00:18,485 [ 45143] SEVERE - #c.i.o.a.i.ApplicationImpl - IntelliJ IDEA 2023.3.6 Build #IC-233.15026.9 2025-05-27 10:00:18,486 [ 45144] SEVERE - #c.i.o.a.i.ApplicationImpl - JDK: 17.0.10; VM: OpenJDK 64-Bit Server VM; Vendor: JetBrains s.r.o. 2025-05-27 10:00:18,486 [ 45144] SEVERE - #c.i.o.a.i.ApplicationImpl - OS: Linux 2025-05-27 10:00:35,395 [ 62053] WARN - #c.i.u.x.Binding - no accessors for com.intellij.ide.util.TipsUsageManager$State 2025-05-27 10:03:08,978 [ 215636] WARN - #c.i.o.o.e.ConfigurableCardPanel - auto-dispose '插件' id=preferences.pluginManager 2025-05-27 10:03:14,142 [ 220800] WARN - #c.i.o.o.e.ConfigurableExtensionPointUtil - ignore deprecated groupId: language for id: preferences.language.Kotlin.scripting 2025-05-27 10:03:49,540 [ 256198] WARN - #c.i.o.o.e.ConfigurableCardPanel - auto-dispose '插件' id=preferences.pluginManager 2025-05-27 10:06:00,498 [ 387156] WARN - #c.i.f.f.SettingsConnectionService - Read timed out java.net.SocketTimeoutException: Read timed out at java.base/sun.nio.ch.NioSocketImpl.timedRead(NioSocketImpl.java:288) at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:314) at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:355) at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:808) at java.base/java.net.Socket$SocketInputStream.read(Socket.java:966) at java.base/sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:484) at java.base/sun.security.ssl.SSLSocketInputRecord.readHeader(SSLSocketInputRecord.java:478) at java.base/sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:160) at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:111) at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1510) at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1425) at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:455) at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:426) at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:589) at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:187) at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1665) at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1589) at java.base/java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:529) at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:308) at com.intellij.util.io.HttpRequests.openConnection(HttpRequests.java:619) at com.intellij.util.io.HttpRequests$RequestImpl.getConnection(HttpRequests.java:361) at com.intellij.util.io.HttpRequests$RequestImpl.getInputStream(HttpRequests.java:369) at com.intellij.facet.frameworks.SettingsConnectionService.lambda$readSettings$0(SettingsConnectionService.java:51) at com.intellij.util.io.HttpRequests.doProcess(HttpRequests.java:524) at com.intellij.util.io.HttpRequests.process(HttpRequests.java:506) at com.intellij.util.io.HttpRequests$RequestBuilderImpl.connect(HttpRequests.java:335) at com.intellij.util.io.RequestBuilder.connect(RequestBuilder.java:58) at com.intellij.facet.frameworks.SettingsConnectionService.readSettings(SettingsConnectionService.java:48) at com.intellij.facet.frameworks.SettingsConnectionService.getSettingValue(SettingsConnectionService.java:75) at com.intellij.facet.frameworks.SettingsConnectionService.getServiceUrl(SettingsConnectionService.java:68) at org.jetbrains.plugins.scala.statistics.CompilerPluginsWhiteList$.createRequestUrl(CompilerPluginsWhiteList.scala:23) at org.jetbrains.plugins.scala.statistics.CompilerPluginsWhiteList$.get$lzycompute(CompilerPluginsWhiteList.scala:15) at org.jetbrains.plugins.scala.statistics.CompilerPluginsWhiteList$.get(CompilerPluginsWhiteList.scala:13) at org.jetbrains.plugins.scala.statistics.ScalaProjectStateCollector$.<clinit>(ScalaProjectStateCollector.scala:75) at org.jetbrains.plugins.scala.statistics.ScalaProjectStateCollector.getGroup(ScalaProjectStateCollector.scala:27) at com.intellij.internal.statistic.service.fus.collectors.FeatureUsagesCollector.getGroupId(FeatureUsagesCollector.java:37) at com.intellij.internal.statistic.service.fus.collectors.FeatureUsagesCollector.isValid(FeatureUsagesCollector.java:27) at com.intellij.internal.statistic.service.fus.collectors.UsageCollectors.isValidCollector(UsageCollectors.kt:53) at com.intellij.internal.statistic.service.fus.collectors.UsageCollectors.access$isValidCollector(UsageCollectors.kt:9) at com.intellij.internal.statistic.service.fus.collectors.UsageCollectors$getProjectCollectors$2.invoke(UsageCollectors.kt:48) at com.intellij.internal.statistic.service.fus.collectors.UsageCollectors$getProjectCollectors$2.invoke(UsageCollectors.kt:48) at kotlin.sequences.FilteringSequence$iterator$1.calcNext(Sequences.kt:171) at kotlin.sequences.FilteringSequence$iterator$1.hasNext(Sequences.kt:194) at kotlin.sequences.SequencesKt___SequencesKt.toList(_Sequences.kt:816) at com.intellij.internal.statistic.service.fus.collectors.UsageCollectors.getProjectCollectors$intellij_platform_statistics(UsageCollectors.kt:49) at com.intellij.internal.statistic.service.fus.collectors.ProjectFUStateUsagesLogger$logProjectState$2.invokeSuspend(FUStateUsagesLogger.kt:225) at com.intellij.internal.statistic.service.fus.collectors.ProjectFUStateUsagesLogger$logProjectState$2.invoke(FUStateUsagesLogger.kt) at com.intellij.internal.statistic.service.fus.collectors.ProjectFUStateUsagesLogger$logProjectState$2.invoke(FUStateUsagesLogger.kt) at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:78) at kotlinx.coroutines.CoroutineScopeKt.coroutineScope(CoroutineScope.kt:264) at com.intellij.internal.statistic.service.fus.collectors.ProjectFUStateUsagesLogger.logProjectState(FUStateUsagesLogger.kt:223) at com.intellij.internal.statistic.service.fus.collectors.ProjectFUStateUsagesLogger.logProjectStateRegularly(FUStateUsagesLogger.kt:218) at com.intellij.internal.statistic.service.fus.collectors.ProjectFUStateUsagesLogger.access$logProjectStateRegularly(FUStateUsagesLogger.kt:198) at com.intellij.internal.statistic.service.fus.collectors.ProjectFUStateUsagesLogger$logProjectStateRegularly$1.invokeSuspend(FUStateUsagesLogger.kt) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684) 2025-05-27 10:22:25,846 [1372504] WARN - #c.i.o.o.e.ConfigurableExtensionPointUtil - ignore deprecated groupId: language for id: preferences.language.Kotlin.scripting 2025-05-27 10:22:28,924 [1375582] SEVERE - #c.i.o.a.i.ApplicationImpl - 连接被拒绝 java.net.ConnectException: 连接被拒绝 at java.base/sun.nio.ch.Net.pollConnect(Native Method) at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:554) at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) at java.base/java.net.Socket.connect(Socket.java:633) at java.base/sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:304) at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:178) at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:533) at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:638) at java.base/sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:266) at java.base/sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:380) at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:193) at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1287) at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1128) at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:179) at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1665) at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1589) at java.base/java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:529) at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:308) at com.intellij.util.io.HttpRequests.openConnection(HttpRequests.java:619) at com.intellij.util.io.HttpRequests$RequestImpl.getConnection(HttpRequests.java:361) at com.intellij.ide.plugins.marketplace.MarketplaceRequests$Companion.readOrUpdateFile$lambda$8(MarketplaceRequests.kt:185) at com.intellij.util.io.HttpRequests.doProcess(HttpRequests.java:524) at com.intellij.util.io.HttpRequests.process(HttpRequests.java:506) at com.intellij.util.io.HttpRequests$RequestBuilderImpl.connect(HttpRequests.java:335) at com.intellij.ide.plugins.marketplace.MarketplaceRequests$Companion.readOrUpdateFile(MarketplaceRequests.kt:182) at com.intellij.ide.plugins.marketplace.MarketplaceRequests.getMarketplacePlugins(MarketplaceRequests.kt:273) at com.intellij.openapi.updateSettings.impl.UpdateChecker.findUpdatesInJetBrainsRepository(UpdateChecker.kt:377) at com.intellij.openapi.updateSettings.impl.UpdateChecker.updateDescriptorsForInstalledPlugins$lambda$6(UpdateChecker.kt:239) at com.intellij.openapi.application.impl.ApplicationImpl$2.run(ApplicationImpl.java:249) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) at com.intellij.util.concurrency.ContextCallable.call(ContextCallable.java:32) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at com.intellij.util.concurrency.ContextRunnable.run(ContextRunnable.java:27) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:702) at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:699) at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1.run(Executors.java:699) at java.base/java.lang.Thread.run(Thread.java:840) 2025-05-27 10:22:28,930 [1375588] SEVERE - #c.i.o.a.i.ApplicationImpl - IntelliJ IDEA 2023.3.6 Build #IC-233.15026.9 2025-05-27 10:22:28,930 [1375588] SEVERE - #c.i.o.a.i.ApplicationImpl - JDK: 17.0.10; VM: OpenJDK 64-Bit Server VM; Vendor: JetBrains s.r.o. 2025-05-27 10:22:28,930 [1375588] SEVERE - #c.i.o.a.i.ApplicationImpl - OS: Linux 2025-05-27 10:22:45,639 [1392297] WARN - #c.i.o.o.e.ConfigurableCardPanel - auto-dispose '插件' id=preferences.pluginManager hadoop@master:/usr/local/idea/bin$
05-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值