日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ThreadPoolExcutor 线程池 异常处理 (上篇)

發(fā)布時間:2023/11/30 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ThreadPoolExcutor 线程池 异常处理 (上篇) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

最近看到crossoverJie的一篇文章:一個線程罷工的詭異事件
首先感謝原作者的分享,自己獲益匪淺。然后是回想到自己的一次面試經(jīng)歷,面試官提問了線程池中的線程出現(xiàn)了異常該怎樣捕獲?會導(dǎo)致什么樣的問題?

示例代碼

public class ThreadPoolException {private final static Logger LOGGER = LoggerFactory.getLogger(ThreadPoolException.class);public static void main(String[] args) throws InterruptedException {ExecutorService execute = new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());execute.execute(new Runnable() {@Overridepublic void run() {LOGGER.info("=====11=======");}});TimeUnit.SECONDS.sleep(5);execute.execute(new Run1());}private static class Run1 implements Runnable {@Overridepublic void run() {int count = 0;while (true) {count++;LOGGER.info("-------222-------------{}", count);if (count == 10) {System.out.println(1 / 0);try {} catch (Exception e) {LOGGER.error("Exception",e);}}if (count == 20) {LOGGER.info("count={}", count);break;}}}} }

上面的代碼是原作者本地調(diào)試的一個代碼,這里我也大致交代下情形:

  • 首先是啟動main方法看最終執(zhí)行現(xiàn)象
  • 這里直接拋異常了,by zero。看到底層是ThreadPoolExecutor 1149行拋出的。
    查看線程dump,發(fā)現(xiàn)線程池中的線程此時處于WAITING狀態(tài)

  • 源碼追蹤
    這里就需要弄清楚為何會出現(xiàn)WAITING狀態(tài),所以我們需要一步步追蹤源碼。
    我們可以在拋異常的地方打斷點,然后一步步跟蹤:
  • 在執(zhí)行1149行代碼由于拋了異常,所以繼續(xù)執(zhí)行finally中processWorkerExit方法:

    processWorkerExit中主要做了兩件事,worker remover和addWorker。線程池中的任務(wù)都會被包裝為一個內(nèi)部 Worker 對象執(zhí)行。不清楚的可以參考:Java并發(fā)之線程池ThreadPoolExecutor源碼學(xué)習(xí)

    最后會執(zhí)行addWorker,緊接著我們繼續(xù)往addWorker中去跟,看看里面做了什么操作:

    addWorker里面是重新new Worker(), 然后執(zhí)行worker.start(), 接著我們看下Worker中的start方法:

    因為Woker是實現(xiàn)Runnable接口的,所以會執(zhí)行其run方法,接著往runWorker方法跟蹤:

    因為此時的Worker是上一步重新new出來的,所以其中的task為空,這時需要繼續(xù)跟蹤getTask()方法:

    此時因為線程池的隊列中并沒有任務(wù),所以這里執(zhí)行take會一直阻塞,也就有了最開始的那個WAITING的狀態(tài)了。
    到了這里一切都很明了了,源碼面前任何妖魔鬼怪都無法藏匿,所以但我們使用線程池的時候一定要注意一異常的捕獲和處理。
    下一章來詳細(xì)解讀一下如何捕獲線程池中的異常。

    由于本人水平有限,文章中如果有不嚴(yán)謹(jǐn)?shù)牡胤竭€請?zhí)岢鰜?#xff0c;愿聞其詳。

    轉(zhuǎn)載于:https://www.cnblogs.com/wang-meng/p/10588637.html

    總結(jié)

    以上是生活随笔為你收集整理的ThreadPoolExcutor 线程池 异常处理 (上篇)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。