java多線程-04-線程池

[TOC]

聲明

該系列文章只是記錄本人回顧java多線程編程時候記錄的筆記。文中所用語言并非嚴謹的專業術語(太嚴謹的術語其實本人也不會……)。難免有理解偏差的地方,歡迎指正。
另外,大神請繞路。不喜勿噴。
畢竟好記性不如爛筆頭嘛,而且許多東西只要不是你經常用的最終都會一丟丟一丟丟地給忘記。

1 線程池簡介

1.2 什么是線程池?

通俗點講,線程池就是一個裝有一大堆線程的容器。
這就和我們通常使用的JDBC的各種數據源有點類似了。數據源里的元素是改造過可重復利用的數據庫連接(Connection)的實例。而線程池里的元素就是可重復利用的線程了。

1.2 使用線程池有什么好處?

  • 降低開銷: 主要是線程的創建和銷毀的開銷(提前創建)
  • 提高響應速度: 省去了線程的創建和銷毀的階段,能立即響應業務處理
  • 更好的管理線程: 線程池是線程的容器, 線程放在容器里更方便統一監控和管理

以下是《java并發編程的藝術》一書中對線程池工作流程的流程圖

線程池的處理流程

2 ThreadPoolExecutor

2.1 相關屬性

ThreadPoolExecutor executor = new ThreadPoolExecutor(
    5, 10, 60, TimeUnit.SECONDS, 
    new ArrayBlockingQueue<>(100)
);
  • corePoolSize: 線程池基本大小
    • 將一個待執行的任務放到線程池中的時候,如果待執行的任務數小于該參數,線程池就會創建一個線程來執行該任務。反之,不再創建新的線程。
    • 在線程池剛剛創建后,線程并不是立即啟動的。如果事先調用了prestartCoreThread()或者prestartAllCoreThreads()方法則會立即啟動核心線程。
  • poolSize: 當前大小(實際線程數)
  • maximumPoolSize: 線程池中所能允許的最大線程數
    • 如果隊列滿了,并且poolSize < maximumPoolSize,在新任務到來后會創建新的線程來執行。
    • 如果底層使用的是無界隊列,該參數將無意義
  • allowCoreThreadTimeOut: 是否允許核心線程超時退出
    • 在沒有任務執行的時候,是否允許核心線程超時退出
    • false: 表示即使是空閑時,核心核心線程也不會退出
  • keepAliveTime: 是否允許線程超時退出
    • 此處指的是超出核心線程數的那部分線程(corePoolSize < poolSize < maximumPoolSize)
    • 而核心線程是否超時退出由allowCoreThreadTimeOut控制
  • workQueue | runnableTaskQueue : 用來保存待執行任務的阻塞隊列
  • threadFactory: 創建線程的工廠
  • RejectedExecutionHandler: 飽和處理策略,見下文

2.2 飽和處理策略

如果使用的是有界隊列,很可能出現隊列和線程池飽和的情況,RejectedExecutionHandler就是用來指定如何處理這種情況的。

內置的四種實現如下:

  • AbortPolicy: 拋出異常
  • CallerRunsPolicy: 在調用execute()方法的線程里執行飽和的任務
  • DiscardOldestPolicy: discards the oldest unhandled request
    • 此處不知道怎么翻譯了,oldest可以理解為最靠近隊首的元素
    • 或者說是最近
  • DiscardPolicy: 直接丟棄

2.3 提交/執行任務

線程池創建好之后,下一步就是向線程池提交任務讓線程池中的線程去執行。
提交的任務必須是Callable或者Runnable的實現類。

提交任務,有如下方法:

public void execute(Runnable command){}

public Future<?> submit(Runnable task){}
public <T> Future<T> submit(Callable<T> task){}
public <T> Future<T> submit(Runnable task, T result){}

其中,execute()方法用于提交沒有返回值的任務。所以無法得知提交的任務什么時候被執行,也無法知道何時執行完畢了。

this.executor.execute(() -> {
    // task to executed
});

submit()方法用于提交帶有返回值的任務。

Future<String> future = this.executor.submit(new Callable<String>() {

    @Override
    public String call() throws Exception {
        return null;
    }
});

try {
    String result = future.get();
    System.out.println(result);
} catch (InterruptedException e) {
    // 中斷
    e.printStackTrace();
} catch (ExecutionException e) {
    // 任務執行錯誤
    e.printStackTrace();
} finally {
    this.executor.shutdown();
}

2.4 停止線程池

提供了兩個方法來終止線程池: shutdown()shutdownNow()

shutdown
shutdownNow

這兩個方法都是通過遍歷線程,逐個調用線程的interrupt()方法來終止線程的。

interrupt

所以問題來了:

無法響應中斷的線程,可能就沒法終止了

另外,在shutdown()方法中,還調用了onShutdown方法。這個方法方法體的實現是空的。
可以重寫這個hook方法來在線程池銷毀的時候完成一些其他的事情。

參考資料

  • 《java并發編程的藝術》
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,527評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,687評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,640評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,957評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,682評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,011評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,009評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,183評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,714評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,435評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,665評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,148評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,838評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,251評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,588評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,379評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,627評論 2 380

推薦閱讀更多精彩內容