iT邦幫忙

0

Android Thread Pool應用01

前言

其實平常做專案滿少直接使用到Thread Pool,大部分專案規模都不大,難度也不高,沒有特別複雜的計算或耗時的操作,最常見的幾乎都是刻UI,Call API。但不管是Call API、或是處理圖片等耗時的行為幾乎也都有套件完美做完了,不過總是不能一輩子用別人做好的套件,總是有需要獨當一面的時候。

這邊我們就討論一下呼叫API或者處理圖片基本上都該會用到的底層行為Thread。

正文

Android原生可用的ThreadPool有幾種,分別是FixedThreadPool、ScheduledThreadPool、CachedThreadPool、SingleThreadExecutor

基本介紹

FixedThreadPool
特性:算是一個基本款的Thread Pool,可以限制同時執行的Thread數量
使用方式如下,newFixedThreadPool帶入的參數就是可同時執行的數量,所以這邊就是最多同時執行兩個Thread
假設一開始執行了四個,頭兩個會先跑,剩下的兩個會等待前面的結束後才逐一補上

ExecutorService mFixedThreadPool = Executors.newFixedThreadPool(2);
mFixedThreadPool.execute(new MyRunnable());

ScheduledThreadPool
特性:可做排程、週期性執行
newScheduledThreadPool同樣是帶入可同時執行的Thread數量,scheduleAtFixedRate/scheduleWithFixedDelay兩者規則不同,使用時要注意一下需求

ScheduledExecutorService mScheduledThreadPool = Executors.newScheduledThreadPool(2);

mScheduledThreadPool.execute(new MyRunnable());

or
//延後500毫秒執行
mScheduledThreadPool.schedule(new MyRunnable(), 500, TimeUnit.MILLISECONDS);

or
//延後1秒執行,每3秒執行一次
mScheduledThreadPool.scheduleAtFixedRate(new MyRunnable(), 1, 3, TimeUnit.SECONDS);

or
//延後1秒執行,每次執行完後等待3秒執行下一次
mScheduledThreadPool.scheduleWithFixedDelay(new MyRunnable(), 1, 3, TimeUnit.SECONDS);

CachedThreadPool
特性:沒有限制數量,Thread在沒有使用時會被回收,60秒內可被重新使用,如果都沒有已回收的執行緒則創建新的

ExecutorService mCacheThreadPool = Executors.newCachedThreadPool();
mCacheThreadPool.execute(new MyRunnable());

SingleThreadExecutor
特性:只用單一個Thread執行

ExecutorService mSingleThreadExecutor = Executors.newSingleThreadExecutor();
mSingleThreadExecutor.execute(new MyRunnable());

實作討論

看完基本介紹後可能會覺得,好像除了ScheduledThreadPool以外,其他的看不出什麼特別明顯的差異
所以這邊就來比較一下,除了ScheduledThreadPool以外其他三個Thread Pool實際跑起來的差別

首先我們創建一個客製化的Runnable,Log一下當下Thread的名稱以及初始化的順序標記
https://ithelp.ithome.com.tw/upload/images/20200521/20126774xDhmhOLY2x.png

在使用FixedThreadPool時,每個Runnable所屬的Thread名稱是不同的
https://ithelp.ithome.com.tw/upload/images/20200521/20126774zHKA40cr3O.png

接下來是CachedThreadPool,pool-1-thread-1 ~ 3重複使用了兩次,符合上面我們所說的,由於每個Runnable需要至少一秒才能執行完,所以幾乎同時執行order 01~03時創建了三組新的Thread(1~3),但等待兩秒後執行order 04~06時,原本的pool-1-thread-1 ~ 3已經都執行完了,馬上拿來重複利用
https://ithelp.ithome.com.tw/upload/images/20200521/20126774mfj4VvINXR.png

再來我們測試另一個狀態的CachedThreadPool,這邊故意等待超過60秒再執行order 04~06,就必須要再創建新的Thread
https://ithelp.ithome.com.tw/upload/images/20200521/20126774vDaTrObzRm.png

最後是SingleThreadExecutor,執行01~06全都在同一個Thread上,仔細看一下Log時間,每一個間隔幾乎可以說是一秒,可以發現這邊可能會發生阻塞、等待的問題
https://ithelp.ithome.com.tw/upload/images/20200521/20126774FLr4Q4ZOq8.png

結論

實作完之後我個人對於Thread Pool應用時機上有大概抓到方向,提供我個人的意見讓大家參考

FixedThreadPool

  • "可能"用於不適合一次跑大量同時進行的行為,就用Fixed限制最大數量,使系統自行分批處理

ScheduledThreadPool

  • 這大概不用多說,很明顯就是排程、週期性相關的行為很適合用

CachedThreadPool

  • 用來做計算類,例如下面這種遊戲,需要算好每個砲彈移動座標
    https://i.gbc.tw/gb_img/3387989l.png

SingleThreadExecutor

  • 由於執行上會必須要等待前一個完成,才能接續執行,或許可以利用這個特性,做一些與順序有關的操作

至於一開始提到的Call API,處理圖片讀取、緩存、二階段緩存等,應該會先使用CachedThreadPool試試看,第二人選則是FixedThreadPool

以上純屬我個人想法,有任何意見、指正或者實際使用案例歡迎分享討論

Android Thread Pool應用02


尚未有邦友留言

立即登入留言