产品中使用了 ThreadPoolExecutor创建线程池,遇到两个不够熟悉的地方,记录一下
1.coresize是线程池的初始化容量,当加入线程池的任务超过coresize时,首先是向等待队列中增加任务,当队列加满后,才会继续新建线程,但是数量不能超过maxpoolsize。
2.我们的多线程任务在执行几天之后会出现activecount一直无法降为0的状况,也就是说有几个线程一直处于挂起状态,占用资源,如果这种情况持续增加,会把线程池占满,那时系统将崩溃。
这个问题的出现,会有很多原因,首先检查的是数据库是否发生锁表或行级锁,是否有文件资源被占用导致死锁。各种情况均排除之后,问题依然得不到解决。找资料,发现jstack可以查看jvm的线程情况。通过jstack pid 发现
"pool-6-thread-19" #219 prio=5 os_prio=0 tid=0x00007f47d8073800 nid=0x6478 runnable [0x00007f4791fe2000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
at sun.security.ssl.InputRecord.read(InputRecord.java:503)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:975)
- locked <0x00000000882db928> (a java.lang.Object)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:933)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
- locked <0x00000000882dba50> (a sun.security.ssl.AppInputStream)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
- locked <0x00000000882dba68> (a java.io.BufferedInputStream)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:735)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:678)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1587)
- locked <0x00000000882dbac0> (a sun.net.www.protocol.https.DelegateHttpsURLConnection)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
- locked <0x00000000882dbac0> (a sun.net.www.protocol.https.DelegateHttpsURLConnection)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:263)
- locked <0x00000000882dbc50> (a sun.net.www.protocol.https.HttpsURLConnectionImpl)
at com.aim.insurance.service.archive.manager.ShangQiManager.post(ShangQiManager.java:274)
at com.aim.insurance.service.archive.manager.ShangQiManager.carInquiry(ShangQiManager.java:127)
at com.aim.insurance.service.inquiry.manager.InquiryManager.asyncInquiry(InquiryManager.java:293)
at com.aim.insurance.service.inquiry.manager.InquiryManager$1.processBusinessLogic(InquiryManager.java:277)
at com.aim.insurance.service.common.AsyncTask.run(AsyncTask.java:35)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
排查到HttpURLConnection在调用http接口的时候挂起了,检查代码,没有设置连接超时时间和读取超时时间,导致线程block阻塞。