「Android 進(jìn)階」線程池學(xué)習(xí)與使用

線程池

0. 前言

線程池概念,以前跟著 Android 視頻有學(xué)習(xí)過(guò),但沒(méi)有真正使用與梳理,間隔 時(shí)間較長(zhǎng)后,忘記的差不多。需要養(yǎng)成良性習(xí)慣,學(xué)習(xí)了新的知識(shí)點(diǎn)后需要梳理,轉(zhuǎn)換為自己理解語(yǔ)言使用技術(shù)文章描述,后續(xù)可以直接查閱筆記。
線程的創(chuàng)建與使用:

1. 線程池

線程池可以理解為同時(shí)管理多個(gè)線程,通過(guò) 線程重用,減少創(chuàng)建與銷毀對(duì)設(shè)備性能消耗,控制線程池中線程的并發(fā)數(shù),避免線程爭(zhēng)奪CPU資源造成阻塞,對(duì)線程進(jìn)行管理,達(dá)到軟件設(shè)計(jì)的需求;

2. 線程池基礎(chǔ)類「ThreadPoolExecutor 」

Execute 作為一個(gè)接口,具體實(shí)現(xiàn)類 ThreadPoolExecutor ;
Android中的線程池都是 直接或間接通過(guò)配置ThreadPoolExecutor 來(lái)實(shí)現(xiàn)不同特性的線程池


//核心線程數(shù),除非allowCoreThreadTimeOut被設(shè)置為true,否則它閑著也不會(huì)死  
int corePoolSize,   
//最大線程數(shù),活動(dòng)線程數(shù)量超過(guò)它,后續(xù)任務(wù)就會(huì)排隊(duì)                     
int maximumPoolSize,   
//超時(shí)時(shí)長(zhǎng),作用于非核心線程(allowCoreThreadTimeOut被設(shè)置為true時(shí)也會(huì)同時(shí)作用于核心線程),閑置超時(shí)便被回收             
long keepAliveTime,                            
//枚舉類型,設(shè)置keepAliveTime的單位,有TimeUnit.MILLISECONDS(ms)、TimeUnit. SECONDS(s)等  
TimeUnit unit,  
//緩沖任務(wù)隊(duì)列,線程池的execute方法會(huì)將Runnable對(duì)象存儲(chǔ)起來(lái)  
BlockingQueue<Runnable> workQueue,  
//線程工廠接口,只有一個(gè)new Thread(Runnable r)方法,可為線程池創(chuàng)建新線程  
ThreadFactory threadFactory) 

ThreadPoolExecutor的各個(gè)參數(shù)所代表的特性注釋中已經(jīng)寫的很清楚了,那么ThreadPoolExecutor執(zhí)行任務(wù)時(shí)的心路歷程是什么樣的呢?(以下用currentSize表示線程池中當(dāng)前線程數(shù)量)
(1) 當(dāng)currentSize<corePoolSize時(shí),直接啟動(dòng)一個(gè)核心線程并執(zhí)行任務(wù)。
(2) 當(dāng)currentSize>=corePoolSize、且workQueue未滿時(shí),添加進(jìn)來(lái)的任務(wù)會(huì)被安排到workQueue中等待執(zhí)行。
(3) 當(dāng)workQueue已滿,但是currentSize<maximumPoolSize時(shí),會(huì)立即開(kāi)啟一個(gè)非核心線程來(lái)執(zhí)行任務(wù)。
(4) 當(dāng)currentSize>=corePoolSize、workQueue已滿、并且currentSize>maximumPoolSize時(shí),調(diào)用handler默認(rèn)拋出RejectExecutionExpection異常。

3. Android 中常用的四類線程池

3.1 FixThreadPool「一堆人排隊(duì)上公廁」

     * @param nThreads the number of threads in the pool
     * @return the newly created thread pool
     * @throws IllegalArgumentException if {@code nThreads <= 0}
     */
    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

// 使用
Executors.newFixThreadPool(5).execute(Runnable);

(1)配置參數(shù),F(xiàn)ixThreadPool : 只有核心線程,數(shù)量固定,不會(huì)被回收,所有線程活動(dòng)是,應(yīng)為隊(duì)列沒(méi)有限制大小,新任務(wù)會(huì)等待執(zhí)行;

3.2 CachedThreadPool「一堆人去一家很大的咖啡館喝咖啡」

     * @param threadFactory the factory to use when creating new threads
     * @return the newly created thread pool
     * @throws NullPointerException if threadFactory is null
     */
    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>(),
                                      threadFactory);
    }

// 使用
Executors.newCachedThreadPool().execute(Runnable);

(1)CachedThreadPool只有非核心線程,最大線程數(shù)非常大,所有線程都活動(dòng)時(shí),會(huì)為新任務(wù)創(chuàng)建新線程,否則利用空閑線程(60s空閑時(shí)間,過(guò)了就會(huì)被回收,所以線程池中有0個(gè)線程的可能)處理任務(wù)。

(2)任務(wù)隊(duì)列SynchronousQueue相當(dāng)于一個(gè)空集合,導(dǎo)致任何任務(wù)都會(huì)被立即執(zhí)行。

(3)【前方高能,筆者腦洞】CachedThreadPool就像是一堆人去一個(gè)很大的咖啡館喝咖啡,里面服務(wù)員也很多,隨時(shí)去,隨時(shí)都可以喝到咖啡。但是為了響應(yīng)國(guó)家的“光盤行動(dòng)”,一個(gè)人喝剩下的咖啡會(huì)被保留60秒,供新來(lái)的客人使用,哈哈哈哈哈,好惡心啊。如果你運(yùn)氣好,沒(méi)有剩下的咖啡,你會(huì)得到一杯新咖啡。但是以前客人剩下的咖啡超過(guò)60秒,就變質(zhì)了,會(huì)被服務(wù)員回收掉。

(4)比較適合執(zhí)行大量的耗時(shí)較少的任務(wù)。喝咖啡人挺多的,喝的時(shí)間也不長(zhǎng)。

3.3 SingleThreadPool「始終只有一個(gè)執(zhí)行線程」

     * {@code newScheduledThreadPool(1)} the returned executor is
     * guaranteed not to be reconfigurable to use additional threads.
     * @return the newly created scheduled executor
     */
    public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
        return new DelegatedScheduledExecutorService
            (new ScheduledThreadPoolExecutor(1));
    }
//使用  
Executors.newSingleThreadPool ().execute(r); 

3.4 ScheduledThreadPool「延遲執(zhí)行和周期重復(fù)執(zhí)行的線程池」

     * @param corePoolSize the number of threads to keep in the pool,
     * even if they are idle
     * @return a newly created scheduled thread pool
     * @throws IllegalArgumentException if {@code corePoolSize < 0}
     */
    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }
//使用,延遲1秒執(zhí)行,每隔2秒執(zhí)行一次Runnable r  
Executors. newScheduledThreadPool (5).scheduleAtFixedRate(r, 1000, 2000, TimeUnit.MILLISECONDS);  

4. 參考文章:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 為什么使用線程池 當(dāng)我們?cè)谑褂镁€程時(shí),如果每次需要一個(gè)線程時(shí)都去創(chuàng)建一個(gè)線程,這樣實(shí)現(xiàn)起來(lái)很簡(jiǎn)單,但是會(huì)有一個(gè)問(wèn)題...
    閩越布衣閱讀 4,416評(píng)論 10 45
  • 前段時(shí)間遇到這樣一個(gè)問(wèn)題,有人問(wèn)微信朋友圈的上傳圖片的功能怎么做才能讓用戶的等待時(shí)間較短,比如說(shuō)一下上傳9張圖片,...
    加油碼農(nóng)閱讀 1,280評(píng)論 0 2
  • 【JAVA 線程】 線程 進(jìn)程:是一個(gè)正在執(zhí)行中的程序。每一個(gè)進(jìn)程執(zhí)行都有一個(gè)執(zhí)行順序。該順序是一個(gè)執(zhí)行路徑,或者...
    Rtia閱讀 2,891評(píng)論 2 20
  • 你問(wèn) 為什么這么久了還單身,到底喜歡怎樣的人呢? 哪里有什么標(biāo)準(zhǔn),說(shuō)不出個(gè)所以然 只不過(guò) 是某一瞬間心動(dòng)的感覺(jué) 可...
    柒玥柒閱讀 449評(píng)論 0 0
  • teat
    一棲閱讀 78評(píng)論 1 0

友情鏈接更多精彩內(nèi)容