五種線程池的對比與使用

今天對五種常見的java內置線程池進行講解。

線程使用的demo

public static void cache() {ExecutorService pool = Executors.newCachedThreadPool();long start = System.currentTimeMillis();pool.execute(() -> {int sum = 0;for (int i = 0; i < 10; i++) {sum = (int) Math.sqrt(i * i - 1 + i);System.out.println(sum);}});System.out.println("cache: " + (System.currentTimeMillis() - start));}

newCachedThreadPool

  • 重用之前的線程
  • 適合執行許多短期異步任務的程序。
  • 調用 execute() 將重用以前構造的線程
  • 如果沒有可用的線程,則創建一個新線程并添加到池中
  • 默認為60s未使用就被終止和移除
  • 長期閑置的池將會不消耗任何資源

源碼:

public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());}

通過源碼可以看出底層調用的是ThreadPoolExecutor方法,傳入一個同步的阻塞隊列實現緩存。

下面說一下ThreadPoolExecutor

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue) {this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), defaultHandler);}

通過源碼可以看出,我們可以傳入線程池的核心線程數(最小線程數),最大線程數量,保持時間,時間單位,阻塞隊列這些參數,最大線程數設置為jvm可用的cpu數量為最佳實踐

newWorkStealingPool

  • 獲取當前可用的線程數量進行創建作為并行級別
  • 使用ForkJoinPool

源碼:

public static ExecutorService newWorkStealingPool() {return new ForkJoinPool(Runtime.getRuntime().availableProcessors(),ForkJoinPool.defaultForkJoinWorkerThreadFactory,null, true);}

通過源碼可以看出底層調用的是ForkJoinPool線程池

下面說一下ForkJoinPool

public ForkJoinPool(int parallelism,ForkJoinWorkerThreadFactory factory,UncaughtExceptionHandler handler,boolean asyncMode) {this(checkParallelism(parallelism),checkFactory(factory),handler,asyncMode ? FIFO_QUEUE : LIFO_QUEUE,"ForkJoinPool-" + nextPoolId() + "-worker-");checkPermission();}

使用一個無限隊列來保存需要執行的任務,可以傳入線程的數量,不傳入,則默認使用當前計算機中可用的cpu數量,使用分治法來解決問題,使用fork()和join()來進行調用

newSingleThreadExecutor

  • 在任何情況下都不會有超過一個任務處于活動狀態
  • 與newFixedThreadPool(1)不同是不能重新配置加入線程,使用FinalizableDelegatedExecutorService進行包裝
  • 能保證執行順序,先提交的先執行。
  • 當線程執行中出現異常,去創建一個新的線程替換之
    源碼:
public static ExecutorService newSingleThreadExecutor() {return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));}

newFixedThreadPool

  • 創建重用固定數量線程的線程池,不能隨時新建線程
  • 當所有線程都處于活動狀態時,如果提交了其他任務,
    他們將在隊列中等待一個線程可用
  • 線程會一直存在,直到調用shutdown

源碼:

public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());}

newScheduledThreadPool

  • 設定延遲時間,定期執行
  • 空閑線程會進行保留

源碼:

return new ScheduledThreadPoolExecutor(corePoolSize);

通過源碼可以看出底層調用的是一個ScheduledThreadPoolExecutor,然后傳入線程數量

下面來介紹一下ScheduledThreadPoolExecutor

public ScheduledThreadPoolExecutor(int corePoolSize) {super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,new DelayedWorkQueue());}

通過源碼可以看出底層調用了ThreadPoolExecutor,維護了一個延遲隊列,可以傳入線程數量,傳入延時的時間等參數,下面給出一個demo

public static void main(String[] args) {ScheduledExecutorService pool = Executors.newScheduledThreadPool(5);for (int i = 0; i < 15; i = i + 5) {pool.schedule(() -> System.out.println("我被執行了,當前時間" + new Date()), i, TimeUnit.SECONDS);}pool.shutdown();}

執行結果

我被執行了,當前時間Fri Jan 12 11:20:41 CST 2018
我被執行了,當前時間Fri Jan 12 11:20:46 CST 2018
我被執行了,當前時間Fri Jan 12 11:20:51 CST 2018

有的小伙伴可能會用疑問,為什么使用schedule()而不使用submit()或者execute()呢,下面通過源碼來分析

    public void execute(Runnable command) {schedule(command, 0, NANOSECONDS);}public Future<?> submit(Runnable task) {return schedule(task, 0, NANOSECONDS);}

通過源碼可以發現這兩個方法都是調用的schedule(),而且將延時時間設置為了0,所以想要實現延時操作,需要直接調用schedule()

下面我們再來分析一下submit()和execute()的以及shutdown()和shutdownNow()的區別

  • submit(),提交一個線程任務,可以接受回調函數的返回值嗎,適用于需要處理返回著或者異常的業務場景
  • execute(),執行一個任務,沒有返回值
  • shutdown(),表示不再接受新任務,但不會強行終止已經提交或者正在執行中的任務
  • shutdownNow(),對于尚未執行的任務全部取消,正在執行的任務全部發出interrupt(),停止執行

五種線程池的適應場景

  1. newCachedThreadPool:用來創建一個可以無限擴大的線程池,適用于服務器負載較輕,執行很多短期異步任務。
  2. newFixedThreadPool:創建一個固定大小的線程池,因為采用無界的阻塞隊列,所以實際線程數量永遠不會變化,適用于可以預測線程數量的業務中,或者服務器負載較重,對當前線程數量進行限制。
  3. newSingleThreadExecutor:創建一個單線程的線程池,適用于需要保證順序執行各個任務,并且在任意時間點,不會有多個線程是活動的場景。
  4. newScheduledThreadPool:可以延時啟動,定時啟動的線程池,適用于需要多個后臺線程執行周期任務的場景。
  5. newWorkStealingPool:創建一個擁有多個任務隊列的線程池,可以減少連接數,創建當前可用cpu數量的線程來并行執行,適用于大耗時的操作,可以并行來執行

?

轉自:https://www.jianshu.com/p/135c89001b61

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

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

相關文章

16進制加法 keil_C/C++編程筆記:C語言進制詳解,二進制、八進制和十六進制

我們平時使用的數字都是由 0~9 共十個數字組成的&#xff0c;例如 1、9、10、297、952 等&#xff0c;一個數字最多能表示九&#xff0c;如果要表示十、十一、二十九、一百等&#xff0c;就需要多個數字組合起來。例如表示 58 的結果&#xff0c;一個數字不夠&#xff0c;只能”…

MySQL的索引是什么?怎么優化?

索引類似大學圖書館建書目索引&#xff0c;可以提高數據檢索的效率&#xff0c;降低數據庫的IO成本。MySQL在300萬條記錄左右性能開始逐漸下降&#xff0c;雖然官方文檔說500~800w記錄&#xff0c;所以大數據量建立索引是非常有必要的。MySQL提供了Explain&#xff0c;用于顯示…

通達信板塊監控指標_通達信洞察強勢板塊指標公式

N:13;P:4;RN:27;VVAR1:(MA(CLOSE,80)-MA(CLOSE,13)/3);VVAR2:( MA((CLOSE-VVAR1)/VVAR1,1));VVAR3:(CLOSE-LLV(LOW,28))/(HHV(HIGH,28)-LLV(LOW,28))*100;VVAR4:SMA(VVAR3,4,1);MMA:EMA(VVAR2,12)*0.7;MMB:EMA(VVAR2,3);快到底:IF(LLV(MMB-MMA,12)>0,0,-20),LINETHICK2,COLO…

12306能刪候補訂單記錄_12306候補購票功能在哪里怎么用 火車票候補購票使用攻略...

12月27日&#xff0c;12306火車票官方推出了一個「候補購票」功能&#xff0c;目前已經開啟春運試點&#xff0c;對于購買火車票的用戶來說&#xff0c;當沒票可買的時候&#xff0c;可以提交候補購票&#xff0c;又多了一種購票途徑了。不過&#xff0c;很多小伙伴對于候補購票…

GIT提交message規范

<type>(<scope>): <subject> <body> <footer> # type 用于說明 commit 的類別&#xff0c;只允許使用下面7個標識。 feat: 新功能&#xff08;feature&#xff09; fix: 修補bug docs: 文檔&#xff08;documentation&#xff09; style: 格…

git實現審核功能_一文教你如何搭建PDD分傭小程序實現財富自由

隨著拼多多的火爆&#xff0c;很多淘客以各種方式通過推廣拼多多商品獲取返傭來月入萬元&#xff0c;實現財富自由。只要你有流量或者足夠努力&#xff0c;像其他淘客一樣實現睡后過萬財富自由不是夢。本文通過詳細教程教你快速搭建屬于自己的PDD分傭小程序&#xff0c;完成自己…

9型轉x型 cobol_蘭州一餐館推鴛鴦牛肉面 9種面型一面多吃

來源標題&#xff1a;蘭州一餐館推鴛鴦牛肉面&#xff0c;清湯酸菜各一邊還有9種面型&#xff0c;網友&#xff1a;能連吃三碗近日&#xff0c;位于甘肅蘭州的一家牛肉面館推出了鴛鴦牛肉面。一個大碗分隔為兩邊&#xff0c;一邊是傳統清湯牛肉面&#xff0c;另一邊是酸菜牛肉面…

gitignore不起作用

.gitignore中已經標明忽略的文件目錄下的文件&#xff0c;git push的時候還會出現在push的目錄中&#xff0c;原因是因為在git忽略目錄中&#xff0c;新建的文件在git中會有緩存&#xff0c;如果某些文件已經被納入了版本管理中&#xff0c;就算是在.gitignore中已經聲明了忽略…

java填空題 在非靜態成員方法中_成本加成定價法的優點有

【單選題】以下Math類的方法中,-4.4通過哪個方法運算后,結果為-5.0?【填空題】以下程序的輸出結果為?【單選題】下列方法定義中,正確的是()【判斷題】Java 中被 final 關鍵字修飾的變量,不能被重新賦值。【簡答題】請按以下要求編寫程序 (1) 創建一個Rectangle類,添加width和…

【算法系列之十三】二叉樹兩葉節點的最大距離

1、題目描述 給定一棵二叉樹&#xff0c;計算這課二叉樹的直徑長度&#xff0c;即為二叉樹任意兩個節點間的最長路徑。比如&#xff1a; 這棵二叉樹的最長路徑為3。 2、解題思路 使用遞歸進行求解&#xff0c;每次遞歸的過程中&#xff0c;先求出以某個節點為樹根的二…

date比較大小 mybatis_Hibernate 和 MyBatis 哪個更好用?

Java大聯盟幫助萬千Java學習者持續成長關注作者&#xff5c;SylvanasSun鄭沐興https://zhuanlan.zhihu.com/p/21966051B 站搜索&#xff1a;楠哥教你學Java獲取更多優質視頻教程前言由于編程思想與數據庫的設計模式不同&#xff0c;生出了一些ORM框架。核心都是將關系型數據庫和…

簡單的cpu飆升排查方法

1先來一段飆升代碼 public class FindJavaThreadInTaskManager {public static void main(String[] args) {Thread thread new Thread(new Worker());thread.start();}static class Worker implements Runnable {Overridepublic void run() {while (true) {System.out.printl…

tortoisesvn創建部署項目_FrameWork如何進行云托管部署

介紹CloudBase Framework 是云開發官方出品的云原生一體化部署工具&#xff0c;可以幫助開發者將靜態網站、后端服務和小程序等應用&#xff0c;一鍵部署到云開發 Serverless 架構的云平臺上&#xff0c;自動伸縮且無需關心運維&#xff0c;聚焦應用本身&#xff0c;無需關心底…

【算法系列之十四】最大子序和

1、題目描述 給定一個整數數組 nums &#xff0c;找到一個具有最大和的連續子數組&#xff08;子數組最少包含一個元素&#xff09;&#xff0c;返回其最大和。 示例: 輸入: [-2,1,-3,4,-1,2,1,-5,4], 輸出: 6 解釋: 連續子數組 [4,-1,2,1] 的和最大&#xff0c;為 6。 2、…

python的代碼復用技術_Python__函數和代碼復用

主要內容函數的定義和使用實例:七段數碼管的繪制代碼復用與函數遞歸PyInstall庫的使用實例&#xff1a;科赫雪花小包裹函數的定義與使用函數的理解與定義函數的使用及調用過程函數的參數傳遞函數的返回值局部變量和全局變量lambda函數------------------------------------函數…

Queue:poll、offer、element、peek的區別

隊列是一種特殊的線性表&#xff0c;它只允許在表的前端&#xff08;front&#xff09;進行刪除操作&#xff0c;而在表的后端&#xff08;rear&#xff09;進行插入操作。進行插入操作的端稱為隊尾&#xff0c;進行刪除操作的端稱為隊頭。隊列中沒有元素時&#xff0c;稱為空隊…

python實現k均值算法_python實現kMeans算法

聚類是一種無監督的學習&#xff0c;將相似的對象放到同一簇中&#xff0c;有點像是全自動分類&#xff0c;簇內的對象越相似&#xff0c;簇間的對象差別越大&#xff0c;則聚類效果越好。1、k均值聚類算法k均值聚類將數據分為k個簇&#xff0c;每個簇通過其質心&#xff0c;即…

mysql給數據量大的表添加索引的辦法

有一個問題&#xff0c;一張表有3百萬條記錄&#xff0c;隨著時間的增加&#xff0c;記錄量會更多&#xff0c;此時查詢速度很慢。在創建此表前沒有未相應字段添加索引&#xff0c;所以此時需要為表添加索引。但是因為數據量大的原因&#xff0c;索引添加不成功&#xff0c;想了…

修改背景圖片_我花了5小時,為網易修改了一份內容超多的PPT,效果超級贊!!...

微信掃碼觀看全套Excel、Word、PPT視頻作者&#xff1a;宋雪賢 來源&#xff1a;PPT進化論(ID&#xff1a;PPTjinhualun)哈嘍&#xff0c;大家好&#xff0c;不知道您看過《我花了3個小時&#xff0c;為京東修改了一份PPT&#xff0c;效果好到驚人&#xff01;》這篇案例修改文…

MySQL千萬級別大表如何優化?

當MySQL單表記錄數過大時&#xff0c;增刪改查性能都會急劇下降&#xff0c;可以參考以下步驟來優化&#xff1a; 單表優化 除非單表數據未來會一直不斷上漲&#xff0c;否則不要一開始就考慮拆分&#xff0c;拆分會帶來邏輯、部署、運維的各種復雜度&#xff0c;一般以整型值…