Android ExecutorService

執(zhí)行一個異步任務你還是new Thread嗎?你知道使用new Thread的弊端嗎?
  1. 每次new Thread新建對象性能差。
  2. 線程缺乏統(tǒng)一管理,可能無限制新建線程,相互之間競爭,及可能占用過多系統(tǒng)資源導致死機或oom。
  3. 缺乏更多功能,如定時執(zhí)行、定期執(zhí)行、線程中斷。
看了以上我推薦使用ExecutorService

相比new Thread,Java提供的四種線程池的好處在于:

  1. 重用存在的線程,減少對象創(chuàng)建、消亡的開銷,性能佳。
  2. 可有效控制最大并發(fā)線程數(shù),提高系統(tǒng)資源的使用率,同時避免過多資源競爭,避免堵塞。
  3. 提供定時執(zhí)行、定期執(zhí)行、單線程、并發(fā)數(shù)控制等功能。
Java通過Executors提供四種線程池,分別為:

1.newCachedThreadPool創(chuàng)建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。

2.newFixedThreadPool 創(chuàng)建一個定長線程池,可控制線程最大并發(fā)數(shù),超出的線程會在隊列中等待。

3.newScheduledThreadPool 創(chuàng)建一個定長線程池,支持定時及周期性任務執(zhí)行。

4.newSingleThreadExecutor 創(chuàng)建一個單線程化的線程池,它只會用唯一的工作線程來執(zhí)行任務,保證所有任務按照指定順序(FIFO, LIFO, 優(yōu)先級)執(zhí)行。

詳解:

(1). newCachedThreadPool

創(chuàng)建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。

(2). newFixedThreadPool

創(chuàng)建一個定長線程池,可控制線程最大并發(fā)數(shù),超出的線程會在隊列中等待,
定長線程池的大小最好根據(jù)系統(tǒng)資源進行設置。如Runtime.getRuntime().availableProcessors()??蓞⒖糚reloadDataCache。

(3) newScheduledThreadPool

創(chuàng)建一個定長線程池,支持定時及周期性任務執(zhí)行;ScheduledExecutorService比Timer更安全,功能更強大

(4)、newSingleThreadExecutor

創(chuàng)建一個單線程化的線程池,它只會用唯一的工作線程來執(zhí)行任務,保證所有任務按照指定順序(FIFO, LIFO, 優(yōu)先級)執(zhí)行?,F(xiàn)行大多數(shù)GUI程序都是單線程的。Android中單線程可用于數(shù)據(jù)庫操作,文件操作,應用批量安裝,應用批量刪除等不適合并發(fā)但可能IO阻塞性及影響UI線程響應的操作

execute(Runnable)

方法 execute(Runnable) 接收1個 java.lang.Runnable 對象作為參數(shù),并且以異步的方式執(zhí)行它,使用這種方式沒有辦法獲取執(zhí)行 Runnable 之后的結果,如果你希望獲取運行之后的返回值,就必須使用 接收 Callable 參數(shù)的 execute() 方法

submit(Runnable)

方法 submit(Runnable) 同樣接收一個 Runnable 的實現(xiàn)作為參數(shù),但是會返回一個 Future 對象。這個 Future 對象可以用于判斷 Runnable 是否結束執(zhí)行

submit(Callable)

方法 submit(Callable) 和方法 submit(Runnable) 比較類似,但是區(qū)別則在于它們接收不同的參數(shù)類型。Callable 的實例與 Runnable 的實例很類似,但是 Callable 的 call() 方法可以返回壹個結果。方法 Runnable.run() 則不能返回結果。

Callable 的返回值可以從方法 submit(Callable) 返回的 Future 對象中獲取

inVokeAny()

方法 invokeAny() 接收壹個包含 Callable 對象的集合作為參數(shù)。調用該方法不會返回 Future 對象,而是返回集合中某壹個 Callable 對象的結果,而且無法保證調用之后返回的結果是哪壹個 Callable,只知道它是這些 Callable 中壹個執(zhí)行結束的 Callable 對象。
如果壹個任務運行完畢或者拋出異常,方法會取消其它的 Callable 的執(zhí)行

invokeAll()

方法 invokeAll() 會調用存在于參數(shù)集合中的所有 Callable 對象,并且返回壹個包含 Future 對象的集合,你可以通過這個返回的集合來管理每個 Callable 的執(zhí)行結果。

需要注意的是,任務有可能因為異常而導致運行結束,所以它可能并不是真的成功運行了。但是我們沒有辦法通過 Future 對象來了解到這個差異

ExecuteService 服務的關閉

使用 ExecutorService 完畢之后,我們應該關閉它,這樣才能保證線程不會繼續(xù)保持運行狀態(tài)。

舉例來說,如果你的程序通過 main() 方法啟動,并且主線程退出了你的程序,如果你還有壹個活動的 ExecutorService 存在于你的程序中,那么程序將會繼續(xù)保持運行狀態(tài)。存在于 ExecutorService 中的活動線程會阻止Java虛擬機關閉。

為了關閉在 ExecutorService 中的線程,你需要調用 shutdown() 方法。ExecutorService
并不會馬上關閉,而是不再接收新的任務,壹但所有的線程結束執(zhí)行當前任務,ExecutorServie 才會真的關閉。

所有在調用 shutdown() 方法之前提交到 ExecutorService 的任務都會執(zhí)行。
如果你希望立即關閉 ExecutorService,你可以調用 shutdownNow() 方法。這個方法會嘗試馬上關閉所有正在執(zhí)行的任務,并且跳過所有已經提交但是還沒有運行的任務。但是對于正在執(zhí)行的任務,是否能夠成功關閉它是無法保證的,有可能他們真的被關閉掉了,也有可能它會壹直執(zhí)行到任務結束。這是壹個最好的嘗試

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

相關閱讀更多精彩內容

  • 進程和線程 進程 所有運行中的任務通常對應一個進程,當一個程序進入內存運行時,即變成一個進程.進程是處于運行過程中...
    勝浩_ae28閱讀 5,257評論 0 23
  • ??一個任務通常就是一個程序,每個運行中的程序就是一個進程。當一個程序運行時,內部可能包含了多個順序執(zhí)行流,每個順...
    OmaiMoon閱讀 1,804評論 0 12
  • https://blog.csdn.net/defonds/article/details/44021605/ 譯...
    huangxiongbiao閱讀 1,391評論 0 11
  • 進程和線程 進程 所有運行中的任務通常對應一個進程,當一個程序進入內存運行時,即變成一個進程.進程是處于運行過程中...
    小徐andorid閱讀 2,993評論 3 53
  • 接口 java.util.concurrent.ExecutorService 表述了異步執(zhí)行的機制,并且可以讓任...
    米刀靈閱讀 11,434評論 0 5

友情鏈接更多精彩內容