久久r热视频,国产午夜精品一区二区三区视频,亚洲精品自拍偷拍,欧美日韩精品二区

您的位置:首頁技術文章
文章詳情頁

淺談Java線程池是如何運行的

瀏覽:5日期:2022-08-20 13:21:24

異步編程工具在Android開發中目前最被推薦的就是Kotlin協程,在引入Kotlin協程機制前,除了響應式擴展(RxJava)兼任異步編程工具外,Java API中線程與線程池就是最重要異步編程手段。而對于Android平臺的Kotlin協程實現來說,依然使用的是線程池來作為任務執行的載體,所以可以將Android平臺的Kotlin協程簡單的理解是對線程池的一種高度封裝。

Executors.newFixedThreadPool(10).asCoroutineDispatcher()Dispatchers.IO.asExecutor()

因此我們先了解Java線程池是如何運行的,再深入理解Kotlin協程是如何實現的。

從Thread到Executor

線程的創建通過Thread類,為了復用線程而進行池化就有了線程池。線程池帶來了兩點明顯優勢:

降低重復創建線程的開銷 將任務與線程管理解耦

Executor接口就是第二點的體現。其execute方法用于執行任務,不必關系這個任務執行的載體究竟是什么,到底有沒有創建線程。ThreadPoolExecutor實現類就是這個任務執行器的線程池實現。

ThreadPoolExecutor的任務添加與線程復用

public void execute(Runnable command) { if (command == null) throw new NullPointerException(); int c = ctl.get(); if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true)) return; c = ctl.get(); }//1 if (isRunning(c) && workQueue.offer(command)) { int recheck = ctl.get(); if (! isRunning(recheck) && remove(command)) reject(command); else if (workerCountOf(recheck) == 0) addWorker(null, false); }//2 else if (!addWorker(command, false)) reject(command);//3 }

查看execute方法可以清楚了解其運行方式:

當線程數小于corePoolSize時,創建線程并執行任務; 若任務未通過步驟1添加,則入隊workQueue;(主要邏輯在if的條件判斷中,而if內的邏輯處理的是在一些異常下,對入隊的回滾或補充創建線程) 若任務未入隊,則仍創建線程(上限為maximumPoolSize)并執行任務,失敗則執行拒絕策略。

boolean addWorker(Runnable firstTask, boolean core)就是創建線程的方法,方法中第二個參數代表以corePoolSize還是maximumPoolSize為界,方法內其余創建線程的細節邏輯不深究。但要關注一下線程的封裝類Worker,addWorker方法內調用了Worker內被封裝線程的start方法,執行Worker的run方法。我們將run方法內的runWorker簡化如下:

void runWorker(Worker w) { Runnable task = w.firstTask; w.firstTask = null; while (task != null || (task = getTask()) != null) { task.run(); } }

可以發現,初始任務執行完后,不斷通過getTask方法獲取任務執行,以此來實現線程的復用,而不是只執行完一個任務就銷毀了線程。

另外查看簡化后的getTask方法如下:

private Runnable getTask() { boolean timed = allowCoreThreadTimeOut || wc > corePoolSize; try { Runnable r = timed ? workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : workQueue.take(); if (r != null) return r; } catch (InterruptedException retry) { } }

任務是從阻塞隊列workQueue中取出的,并且根據配置allowCoreThreadTimeOut與線程個數是否大于corePoolSize,來決定使用BlockingQueue<Runable>的帶超時時間的取任務方法poll,還是阻塞取任務方法take,以實現任務列表為空時適時銷毀線程還是阻塞線程。

回過頭來看ThreadPoolExecutor的構造方法:

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

我們可以清楚的明白每個參數的含義,以及它是如何影響線程池中線程的復用了。

到此這篇關于淺談Java線程池是如何運行的的文章就介紹到這了,更多相關Java 線程池內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Java
相關文章:
主站蜘蛛池模板: 中牟县| 长春市| 竹溪县| 崇礼县| 宁远县| 东港市| 安岳县| 南通市| 上饶县| 太白县| 乐清市| 县级市| 烟台市| 邢台市| 吉首市| 周至县| 定日县| 鄂托克旗| 莱芜市| 崇文区| 屏东市| 陈巴尔虎旗| 自治县| 抚松县| 如东县| 中牟县| 茶陵县| 赣榆县| 宁波市| 余江县| 曲沃县| 吴桥县| 张家口市| 若羌县| 仁化县| 滦南县| 淳化县| 水城县| 姜堰市| 伊金霍洛旗| 阳城县|