自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

面試官:說一下線程池內部工作原理?

開發(fā) 后端
在Java中有一個Executors工具類,可以為我們創(chuàng)建一個線程池,其本質就是new了一個ThreadPoolExecutor對象。線程池幾乎也是面試必考問題。本節(jié)結合源代碼,說說ThreadExecutor的工作原理。

[[403251]]

 隨著cpu核數越來越多,不可避免的利用多線程技術以充分利用其計算能力。所以,多線程技術是服務端開發(fā)人員必須掌握的技術。

線程的創(chuàng)建和銷毀,都涉及到系統(tǒng)調用,比較消耗系統(tǒng)資源,所以就引入了線程池技術,避免頻繁的線程創(chuàng)建和銷毀。

在Java中有一個Executors工具類,可以為我們創(chuàng)建一個線程池,其本質就是new了一個ThreadPoolExecutor對象。線程池幾乎也是面試必考問題。本節(jié)結合源代碼,說說ThreadExecutor的工作原理

一、線程池創(chuàng)建

先看一下ThreadPoolExecutor參數最全的構造方法:

圖片

  •  corePoolSize: 線程池的核心線程數,說白了就是,即便是線程池里沒有任何任務,也會有corePoolSize個線程在候著等任務。
  •  maximumPoolSize: 最大線程數,不管你提交多少任務,線程池里最多工作線程數就是maximumPoolSize。
  •  keepAliveTime: 線程的存活時間。當線程池里的線程數大于corePoolSize時,如果等了keepAliveTime時長還沒有任務可執(zhí)行,則線程退出。
  •  unit: 這個用來指定keepAliveTime的單位,比如秒:TimeUnit.SECONDS。
  •  workQueue: 一個阻塞隊列,提交的任務將會被放到這個隊列里。
  •  threadFactory: 線程工廠,用來創(chuàng)建線程,主要是為了給線程起名字,默認工廠的線程名字:pool-1-thread-3。
  •  handler: 拒絕策略,當線程池里線程被耗盡,且隊列也滿了的時候會調用。

以上就是創(chuàng)建線程池時用到的參數,面試中經常會有面試官問到這個問題。

二、線程池執(zhí)行流程

這里用一個圖來說明線程池的執(zhí)行流程

圖片

任務被提交到線程池,會先判斷當前線程數量是否小于corePoolSize,如果小于則創(chuàng)建線程來執(zhí)行提交的任務,否則將任務放入workQueue隊列,如果workQueue滿了,則判斷當前線程數量是否小于maximumPoolSize,如果小于則創(chuàng)建線程執(zhí)行任務,否則就會調用handler,以表示線程池拒絕接收任務。

這里以jdk1.8.0_111的源代碼為例,看一下具體實現。

1、先看一下線程池的executor方法

圖片

  •  判斷當前活躍線程數是否小于corePoolSize,如果小于,則調用addWorker創(chuàng)建線程執(zhí)行任務
  •  如果不小于corePoolSize,則將任務添加到workQueue隊列。
  •  如果放入workQueue失敗,則創(chuàng)建線程執(zhí)行任務,如果這時創(chuàng)建線程失敗(當前線程數不小于maximumPoolSize時),就會調用reject(內部調用handler)拒絕接受任務。

2、再看下addWorker的方法實現

這塊代碼是在創(chuàng)建非核心線程時,即core等于false。判斷當前線程數是否大于等于maximumPoolSize,如果大于等于則返回false,即上邊說到的③中創(chuàng)建線程失敗的情況。

addWorker方法的下半部分:

圖片

  •  創(chuàng)建Worker對象,同時也會實例化一個Thread對象。
  •  啟動啟動這個線程

3、再到Worker里看看其實現

圖片

可以看到在創(chuàng)建Worker時會調用threadFactory來創(chuàng)建一個線程。上邊的②中啟動一個線程就會觸發(fā)Worker的run方法被線程調用。

4、接下來咱們看看runWorker方法的邏輯

圖片

線程調用runWoker,會while循環(huán)調用getTask方法從workerQueue里讀取任務,然后執(zhí)行任務。只要getTask方法不返回null,此線程就不會退出。

5、最后在看看getTask方法實現

圖片

  •  咱們先不管allowCoreThreadTimeOut,這個變量默認值是false。wc>corePoolSize則是判斷當前線程數是否大于corePoolSize。
  •  如果當前線程數大于corePoolSize,則會調用workQueue的poll方法獲取任務,超時時間是keepAliveTime。如果超過keepAliveTime時長,poll返回了null,上邊提到的while循序就會退出,線程也就執(zhí)行完了。

如果當前線程數小于corePoolSize,則會調用workQueue的take方法阻塞在當前。 

 

責任編輯:龐桂玉 來源: Java知音
相關推薦

2022-06-06 15:33:20

線程Java釋放鎖

2023-09-12 14:56:13

MyBatis緩存機制

2024-02-21 16:42:00

2024-02-27 15:23:48

RedLock算法Redis

2023-12-29 13:45:00

2024-01-29 10:08:11

零拷貝Zero-copyCPU 拷貝

2025-03-10 07:05:07

2021-07-28 10:08:19

類加載代碼塊面試

2022-06-07 12:03:33

Java內存模型

2023-02-08 08:32:41

輪詢鎖

2023-02-18 13:34:14

Nacos健康檢查機制

2023-11-29 08:00:53

JavaTreeMap底層

2023-11-29 16:38:12

線程池阻塞隊列開發(fā)

2020-07-30 07:58:36

加密算法

2024-03-11 18:18:58

項目Spring線程池

2023-01-30 15:39:40

GETHTTP

2022-02-17 08:02:08

線程Java生命周期

2022-03-09 07:35:24

線程池線程參數

2021-11-27 08:13:13

Final 面試

2024-08-09 09:01:08

原型鏈JavaScriptstudent1?
點贊
收藏

51CTO技術棧公眾號