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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

[Java并发编程(二)] 线程池 FixedThreadPool、CachedThreadPool、ForkJoinPool?为后台任务选择合适的 Java executors...

發布時間:2025/4/14 java 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Java并发编程(二)] 线程池 FixedThreadPool、CachedThreadPool、ForkJoinPool?为后台任务选择合适的 Java executors... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

[Java并發編程(二)] 線程池 FixedThreadPool、CachedThreadPool、ForkJoinPool?為后臺任務選擇合適的 Java executors ...

摘要

Java 和其他平臺相比最大的優勢在于它可以很好的利用資源來進行并行計算。確實,在 JVM 上可以輕而易舉地在后臺執行一段代碼,并在需要使用它的時候消費計算的結果。同時,它也讓開發者可以更好的利用現代計算機硬件所帶來計算能力。

但是,想讓計算正確并不容易,或許對于開發者最大的挑戰是編寫一個總是能運行正確的程序,而不是我們熟悉的 “在我機器上” 是正確的。

這篇文章會看看 Executor 里提供的不同選擇。

正文

Java Executors 詳解

簡言之,Executor 是一個接口,它旨在將任務的聲明與實際計算解耦。

public interface Executor {void execute(Runnable command);}

它以 Runnable 實例的形式接受任務。線程會在某個時間點獲取任務并執行 Runnable::run 方法。但是,真正有難度的通常是如何選擇將要使用的 Executor 實現。在 Executors 類中已經有一些可供使用的默認實現。讓我們來看看它們是什么以及何時選擇。

總體上說,當選擇供后臺計算的 Executor 時,通常可以考慮 3 個主要的問題:

  • 默認希望有多少個線程并行執行?
  • 當所有可用線程都處于忙碌狀態時,Executor 會如何處理一個提交的任務?(如:通常它要么使用更多的線程或者要么將任務加入到隊列中)
  • 是否希望限制任務隊列的大小,如果隊列滿了會怎樣?

如果希望顯式地控制這些問題的答案,可以使用 JDK 提供的靈活的 API 來創建自己的 ThreadPoolExecutor 。ThreadPoolExecutor 的構造器顯式地要求提供問題的答案:

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)

以下描述了這些參數的含義以及它們是如何回答以上問題的:

  • int corePoolSize - 線程池初始啟動時線程的數量
  • int maximumPoolSize - 當核心線程繁忙時,希望線程池增長的最大值
  • long keepAliveTime, TimeUnit 單位 - 如果線程空閑不再工作,是否希望關閉它?線程池需要等待多久才關閉它?
  • BlockingQueue workQueue - 任務如果不能立即處理是如何處理的?是否希望限制任務隊列的大小?
  • RejectedExecutionHandler handler - 如果 Executor 不接受任務會怎樣?是否應該拋出異常?調用方是否應該自行處理任務?

下面列出了由工廠方法 Executors 創建的不同 ExecutorServices 的差異。希望對在面臨如上問題并做出選擇時有幫助。

newFixedThreadPool(int nThread) - n 個線程會同時進行處理,當線程池滿后,新的任務會被加入到大小沒有限制的隊列中。比較適合 CPU 密集型的任務。

newWorkStealingPool(int parallelism) - 會更加所需的并行層次來動態創建和關閉線程。它同樣會試圖減少任務隊列的大小,所以比較適于高負載的環境。同樣也比較適用于當執行的任務會創建更多任務,如遞歸任務。

newSingleThreadExecutor() - 創建一個不可配置的 newFixedThreadPool(1),所以一個線程會執行所有的任務。它適用于明確知道可預測性以及任務需要按順序執行的情況。

newCachedThreadPool() - 不會將任務加入隊列。可以將它看成一個最大值為 0 的隊列。如果當前線程都處于繁忙狀態,它會創建另外一個線程來執行任務。它有時也會重用線程。它適用于防止 DOS 攻擊。緩存線程池的問題在于它不知道該合適停止創建線程。設想需要執行大量計算的任務時,如果將任務提交給 Executor ,更多的線程會消耗更多的 CPU,同時每個任務的執行也會花更長時間。這是個多米諾效應,有更多的任務會被記錄下。這樣越來越多的線程會被創建,而任務的執行會更慢。很難解決這個負反饋環的問題。

所以對于大多數情況, Executors::newFixedThreadPool(int nThreads) 是當我們想要使用線程池時首先考慮的選擇對象。對于計算密集型的任務它通常能提供近于最優的吞吐量,對于 IO 密集型的任務也不會使任何問題變得更糟。至少如果在我們使用這些 Executor 遇到問題并進行性能調優時,不會毫無頭緒。

ForkJoinPool 與 ManagedBlockers

當然 JVM 上有一個默認選擇的 Executor:通用的 ForkJoinPool,它是由 JVM 預設的用來并行處理流以及執行類似 CompletableFuture::supplyAsync 的任務。

聽起來很美?預設的,隨時隨地可用,最先進的線程池。還希望哪些其他的特性?這里有個忠告,如果有件事情聽起來太好了,那么一定需要擦亮眼睛。ForkJoinPool 簡直太好了,除了它是通用的 common ,(即被整個 JVM 共享),它可以被在同一 JVM 進程內的所有、任何組件使用。

如果不小心讓不合適的任務污染了它,可能會讓整個 JVM 進程受到影響。所以如果不小心讓 common 池中的工作線程阻塞,可能是沒有正確地使用它。

讓我們來看看如何讓它變得更好。ForkJoinPool 設計的初衷是為了解決有些任務會阻塞工作線程的情況,所以它提供了處理這種阻塞的 API 。

讓我們歡迎 — ManagedBlocker - 可以用它來給 ForkJoinPool 傳遞信號擴展它的并行能力,從而補償潛在可能被阻塞的工作線程。

假設我們有一個 Call 實例,與 Retrofit 2 Call 類似,它包含所有查詢所需要的 endpoint 信息,以及如何將結果轉換成對象的信息。開始使用 Retrofit 2,盡管這篇文章主要是寫 Android ,但總體的概念與在 JVM 上使用 Retrofit 是一樣的。它提供了一套很好的 HTTP 請求的 API 。

class WS<E> implements ManagedBlocker {private final Call<E> call;volatile E item = null;public WS(Call<E> call) {this.call = call;}public boolean block() throws InterruptedException {if (item == null)item = call.execute().body();return true;}public boolean isReleasable() {return item != null;}public E getItem() { // call after pool.managedBlock completesreturn item;}}

現在,當我們想要調用 Call::execute 的時候,我們需要保證它是通過 ForkJoinPool::managedBlock 方法進行調用的

WS ws = new WS(call);ForkJoinPool.managedBlock(ws);ws.getItem(); // obtain the result

顯然,當在 FJP 以外運行的時候它毫無意義,在線程池上運行時才有意義。FJP 會在線程出現阻塞時生成多的工作線程。需要提醒的是,這并不是銀彈,相反,很有可能是錯誤的,因為 ManagedBlocker API 是用來處理可能被阻塞的 synchronizer 對象的。這里我們是在處理一個阻塞網絡調用,它可以處理當我們查詢 4 個 urls FJP 計算資源被耗盡的情況。

總結

本篇文章我看了 Executors 類提供給我們的選擇,以及何時使用各個 Executor 的策略。對于 CPU 密集型的任務,newFixedThreadPool 可以適用大多數場景,除非明確知道另外一個選擇更好。但是,對于 IO 密集型的任務,并不簡單。可以通過將 IO 調用包裝到 ManagedBlocker 里并使用 ForkJoinPool 來增強它內部的并行能力。

參考

zeroturnaround: FixedThreadPool, CachedThreadPool, or ForkJoinPool? Picking correct Java executors for background tasks

結束

轉載于:https://www.cnblogs.com/richaaaard/p/6601445.html

總結

以上是生活随笔為你收集整理的[Java并发编程(二)] 线程池 FixedThreadPool、CachedThreadPool、ForkJoinPool?为后台任务选择合适的 Java executors...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲ⅴ国产v天堂a无码二区 | 国产乱子一区二区 | 精品一区三区 | 日本激情影院 | 手机看片国产日韩 | 色欲av伊人久久大香线蕉影院 | 日韩小视频 | 日韩欧美精品久久 | 黄色网页在线看 | 国产永久免费视频 | av片在线播放 | 日韩国产亚洲欧美 | 四虎福利视频 | 天堂av手机版 | 在线不卡免费视频 | 中文字幕在线观看免费 | 久久亚洲AV无码 | 欧美精品v国产精品v日韩精品 | 五月激情婷婷网 | 福利第一页| 国产精品一区二区三区不卡 | 久久97人妻无码一区二区三区 | 依依成人在线 | 国产最新网址 | a毛片在线 | 男生和女生差差视频 | 黄色香港三级三级三级 | 久久亚洲综合色图 | 噼里啪啦动漫高清在线观看 | 毛片在线看片 | 爱吃波客今天最新视频 | 日本一区二区视频在线播放 | 91麻豆国产在线观看 | 伊人影视久久 | 亚洲欧美日韩国产综合 | 亚洲热影院 | 亚洲国产第一 | 国产免费一区二区三区最新不卡 | 88久久精品无码一区二区毛片 | 国产乱淫av | 伊人久久久久久久久久久久久 | 蜜桃精品视频在线观看 | 久久久久99精品国产片 | 欧洲女性下面有没有毛发 | 黄色激情视频网站 | 鲁一鲁在线 | 国产区二区 | 日本丰满少妇做爰爽爽 | 亚洲激情文学 | 四虎免费影视 | 亚洲精品~无码抽插 | 麻豆专区| 91av国产视频| 午夜手机福利 | 日韩有码在线播放 | 亚洲男人的天堂在线视频 | 国产原创在线播放 | 大胸喷奶水www视频妖精网站 | 毛片毛片毛片毛片 | av黄色在线观看 | 一本色道久久综合亚洲二区三区 | 国产又色又爽又高潮免费 | 亚洲一区二区三区电影在线观看 | 亚洲成人aaa | 91久久国产综合久久 | 免费在线观看黄色av | 95国产精品 | 国产成人影视 | 一区二区三区视频在线免费观看 | 青青免费视频 | 久久精品一区二区三区黑人印度 | 福利小视频在线播放 | 欧美日韩免费 | 日本精品少妇 | 亚洲伊人影院 | 中文字幕二区在线观看 | xxxx视频在线| 99精品久久久久久久婷婷 | 国产主播精品 | 国产成人精品无码播放 | 欧美肥老妇视频九色 | 五月在线| 成了校长的性脔h文 | 午夜精品成人 | 播色网 | 国产日韩欧美精品在线观看 | av在线h| 国产毛片毛片毛片毛片毛片毛片 | 韩国福利一区 | 日本bbwbbw| 国产性精品 | 国产99在线 | 久久草视频 | 青娱乐在线视频免费观看 | 日韩精品久久久久久久电影99爱 | 日韩精品一区在线视频 | 欧美性生活网站 | 综合国产一区 | 亚洲天堂成人在线观看 |