本篇文章給大家分享的是有關Java中的線程池是如何運行的,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
異步編程工具在Android開發(fā)中目前最被推薦的就是Kotlin協(xié)程,在引入Kotlin協(xié)程機制前,除了響應式擴展(RxJava)兼任異步編程工具外,Java API中線程與線程池就是最重要異步編程手段。而對于Android平臺的Kotlin協(xié)程實現(xiàn)來說,依然使用的是線程池來作為任務執(zhí)行的載體,所以可以將Android平臺的Kotlin協(xié)程簡單的理解是對線程池的一種高度封裝。
Executors.newFixedThreadPool(10).asCoroutineDispatcher() Dispatchers.IO.asExecutor()
因此我們先了解Java線程池是如何運行的,再深入理解Kotlin協(xié)程是如何實現(xiàn)的。
從Thread到Executor
線程的創(chuàng)建通過Thread類,為了復用線程而進行池化就有了線程池。線程池帶來了兩點明顯優(yōu)勢:
降低重復創(chuàng)建線程的開銷
將任務與線程管理解耦
Executor接口就是第二點的體現(xiàn)。其execute方法用于執(zhí)行任務,不必關系這個任務執(zhí)行的載體究竟是什么,到底有沒有創(chuàng)建線程。ThreadPoolExecutor實現(xiàn)類就是這個任務執(zhí)行器的線程池實現(xiàn)。
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方法可以清楚了解其運行方式:
當線程數(shù)小于corePoolSize時,創(chuàng)建線程并執(zhí)行任務;
若任務未通過步驟1添加,則入隊workQueue;(主要邏輯在if的條件判斷中,而if內的邏輯處理的是在一些異常下,對入隊的回滾或補充創(chuàng)建線程)
若任務未入隊,則仍創(chuàng)建線程(上限為maximumPoolSize)并執(zhí)行任務,失敗則執(zhí)行拒絕策略。
boolean addWorker(Runnable firstTask, boolean core)
就是創(chuàng)建線程的方法,方法中第二個參數(shù)代表以corePoolSize還是maximumPoolSize為界,方法內其余創(chuàng)建線程的細節(jié)邏輯不深究。但要關注一下線程的封裝類Worker,addWorker方法內調用了Worker內被封裝線程的start方法,執(zhí)行Worker的run方法。我們將run方法內的runWorker簡化如下:
void runWorker(Worker w) { Runnable task = w.firstTask; w.firstTask = null; while (task != null || (task = getTask()) != null) { task.run(); } }
可以發(fā)現(xiàn),初始任務執(zhí)行完后,不斷通過getTask方法獲取任務執(zhí)行,以此來實現(xiàn)線程的復用,而不是只執(zhí)行完一個任務就銷毀了線程。
另外查看簡化后的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中取出的,并且根據(jù)配置allowCoreThreadTimeOut與線程個數(shù)是否大于corePoolSize,來決定使用BlockingQueue<Runable>的帶超時時間的取任務方法poll,還是阻塞取任務方法take,以實現(xiàn)任務列表為空時適時銷毀線程還是阻塞線程。
回過頭來看ThreadPoolExecutor的構造方法:
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
以上就是Java中的線程池是如何運行的,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
網站名稱:Java中的線程池是如何運行的-創(chuàng)新互聯(lián)
文章路徑:http://www.rwnh.cn/article36/csjjpg.html
成都網站建設公司_創(chuàng)新互聯(lián),為您提供品牌網站制作、外貿網站建設、App開發(fā)、網站建設、標簽優(yōu)化、軟件開發(fā)
聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)