ThreadPoolExcutor 線程池 異常處理 (上篇)

前言

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

示例代碼

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;}}}}
}

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

  1. 首先是啟動main方法看最終執行現象
    799093-20190324161104014-1543242339.png

這里直接拋異常了,by zero。看到底層是ThreadPoolExecutor 1149行拋出的。
查看線程dump,發現線程池中的線程此時處于WAITING狀態
799093-20190324161123892-1046852662.png

  1. 源碼追蹤
    這里就需要弄清楚為何會出現WAITING狀態,所以我們需要一步步追蹤源碼。
    我們可以在拋異常的地方打斷點,然后一步步跟蹤:
    799093-20190324161142428-560186507.png

在執行1149行代碼由于拋了異常,所以繼續執行finally中processWorkerExit方法:
799093-20190324161158755-961625712.png

processWorkerExit中主要做了兩件事,worker remover和addWorker。線程池中的任務都會被包裝為一個內部 Worker 對象執行。不清楚的可以參考:Java并發之線程池ThreadPoolExecutor源碼學習
799093-20190324161219474-767111181.png

最后會執行addWorker,緊接著我們繼續往addWorker中去跟,看看里面做了什么操作:
799093-20190324161236882-1819871297.png

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

因為Woker是實現Runnable接口的,所以會執行其run方法,接著往runWorker方法跟蹤:
799093-20190324161315293-1162072966.png

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

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

由于本人水平有限,文章中如果有不嚴謹的地方還請提出來,愿聞其詳。

轉載于:https://www.cnblogs.com/wang-meng/p/10588637.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/387173.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/387173.shtml
英文地址,請注明出處:http://en.pswp.cn/news/387173.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

3 MapReduce計算模型

MapReduce被廣泛應用于日志分析、海量數據排序、在海量數據中查找特定模式等場景中。 MapReduceJob 在Hadoop中&#xff0c;每個MapReduce任務都被初始化為一個Job。 每個Job又可以分為兩個階段&#xff1a;Map階段和Reduce階段。這兩個階段分別用Map函數和Reduce函數來表示。…

ionic3 調用本地相冊并上傳圖片

前言在APP中啟動相冊選擇器或者拍照上傳圖片這些功能是非常常見的。對于Ionic2&#xff0c;我們只能通過cordova插件實現調用原生的功能。下面將簡單的封裝一個選擇相冊或拍照上傳圖片的ImgService服務。具體如下。 Cordova準備下載安裝所需的Cordovar插件&#xff1a; Image P…

Mapreduce中maptask過程詳解

一、Maptask并行度與決定機制 1.一個job任務的map階段的并行度默認是由該任務的大小決定的&#xff1b; 2.一個split切分分配一個maprask來并行處理&#xff1b; 3.默認情況下&#xff0c;split切分的大小等于blocksize大小&#xff1b; 4.切片不是mapper類中對單詞的切片&…

4 開發MapReduce應用程序

系統參數配置 Configuration類由源來設置&#xff0c;每個源包含以XML形式出現的一系列屬性/值對。如&#xff1a; configuration-default.xml configuration-site.xml Configuration conf new Configuration(); conf.addResource("configuraition-default.xml"…

實用的HTML5的上傳圖片方法

<input type"file" accept"video/*;capturecamcorder"> <input type"file" accept"audio/*;capturemicrophone"><input type"file" accept"image/*;capturecamera">直接調用相機<input type…

3.11 列出完數

完數&#xff1a;一個數恰好等于不包括自身的所有不同因子之和。如6123。 輸入&#xff1a;每一行含有一個整數n。 輸出&#xff1a;對每個整數n&#xff0c;輸出所有不大于n的完數。輸出格式為&#xff1a;整數n&#xff0c;冒號&#xff0c;空格&#xff0c;完數&#xff0…

angularjs 上傳

xxx.module.ts模塊 import { NgModule} from “angular/core”; import { FileUploadModule } from “ng2-file-upload” ; import { XXXComponent } from “./xxx.component”; NgModule({ imports:[ FileUploadModule ], declarations:[ XXXComponent &#xff0c;/component…

PHPCMS的產品篩選功能

如下圖所示功能&#xff1a; 首先&#xff0c;用下面這些代碼替換掉phpcms/libs/functions/extention.func.php的內容 <?php /*** extention.func.php 用戶自定義函數庫** copyright (C) 2005-2010 PHPCMS* license http://www.phpcms.cn/licen…

框架使用SpringBoot + Spring Security Oauth2 +PostMan

框架使用SpringBoot Spring Security Oauth2 主要完成了客戶端授權 可以通過mysql數據庫讀取當前客戶端表信息進行驗證&#xff0c;token存儲在數據庫中 1.引入依賴 oauth2 依賴于spring security&#xff0c;需要引入spring&#xff0c; mysql&#xff0c;redis&#xff0c; …

3.12 12!配對

找出輸入數據中所有兩兩相乘的積為12!的個數。 輸入樣例&#xff1a; 1 10000 159667200 9696 38373635 1000000 479001600 3 1 479001600 輸出樣例&#xff1a; 3 有3對&#xff1a; 1 479001600 1 479001600 3 159667200 #include<iostream> #include<fstre…

程序員自身價值值這么多錢么?

xx 網絡公司人均獎金 28 個月…… xx 科技公司人均獎金 35 個月…… 每到年底&#xff0c;這樣的新聞在互聯網業內簡直是鋪天蓋地。那些獎金不高的程序員們一邊羨慕嫉妒&#xff0c;一邊暗暗比較一下自己的身價&#xff0c;考慮是不是該跳槽了。 不同水平的程序員&#xff0c;薪…

3.13 判讀是否是對稱素數

輸入&#xff1a;11 101 272 輸出&#xff1a; Yes Yes No #include<fstream> #include<iostream> #include<sstream> #include<string> #include<cmath> using namespace std;bool isPrime(int); bool isSymmetry(int);int main(){ifstream…

Spring MVC中使用 Swagger2 構建Restful API

0.Spring MVC配置文件中的配置[java] view plaincopy<!-- 設置使用注解的類所在的jar包&#xff0c;只加載controller類 --> <span style"white-space:pre"> </span><context:component-scan base-package"com.jay.plat.config.contro…

Go語言規范匯總

目錄 統一規范篇合理規劃目錄GOPATH設置import 規范代碼風格大小約定命名篇基本命令規范項目目錄名包名文件名常量變量變量申明變量命名慣例全局變量名局部變量名循環變量結構體(struct)接口名函數和方法名參數名返回值開發篇包魔鬼數字常量 & 枚舉結構體運算符函數參數返回…

3.14 01串排序

將01串首先按照長度排序&#xff0c;其次按1的個數的多少排序&#xff0c;最后按ASCII碼排序。 輸入樣例&#xff1a; 10011111 00001101 10110101 1 0 1100 輸出樣例&#xff1a; 0 1 1100 1010101 00001101 10011111 #include<fstream> #include<iost…

platform(win32) 錯誤

運行cnpm install后&#xff0c;出現雖然提示不適合Windows&#xff0c;但是問題好像是sass loader出問題的。所以只要執行下面命令即可&#xff1b;方案一&#xff1a;cnpm rebuild node-sass #不放心可以重新安裝下 cnpm install方案二&#xff1a;npm update npm install no…

Error: Program type already present: okhttp3.Authenticator$1

在app中的build.gradle中加入如下代碼&#xff0c; configurations {all*.exclude group: com.google.code.gsonall*.exclude group: com.squareup.okhttp3all*.exclude group: com.squareup.okioall*.exclude group: com.android.support,module:support-v13 } 如圖 轉載于:ht…

3.15 排列對稱串

篩選出對稱字符串&#xff0c;然后將其排序。 輸入樣例&#xff1a; 123321 123454321 123 321 sdfsdfd 121212 \\dd\\ 輸出樣例 123321 \\dd\\ 123454321 #include<fstream> #include<iostream> #include<string> #include<set> using …

ES6規范 ESLint

在團隊的項目開發過程中&#xff0c;代碼維護所占的時間比重往往大于新功能的開發。因此編寫符合團隊編碼規范的代碼是至關重要的&#xff0c;這樣做不僅可以很大程度地避免基本語法錯誤&#xff0c;也保證了代碼的可讀性&#xff0c;畢竟&#xff1a;程序是寫給人讀的&#xf…

前端 HTML 常用標簽 head標簽相關內容 script標簽

script標簽 定義JavaScript代碼 <!--定義JavaScript代碼--> <script type"text/javascript"></script> 引入JavaScript文件 src""引入的 js文件路徑 <!-- 引入JavaScript文件 --> <script src"./index.js"></s…