1.概述
線程在Android中是一個非常重要的概念,分爲主線程和子線程,主線程主要負責與界面有關的操作,而子線程負責其他耗時的操作,不能將耗時操作放在主線程中,不然會引發ANR問題。
線程池可以看做是一個線程的集合,提供了簡單的幾種管理方法,使用線程池有幾個好處:
- 線程複用,重用池中的線程避免過多的開銷;
- 有效控制最大線程的數量,不會因爲開啓過多的線程而造成阻塞;
- 簡單的管理,並能夠設置定時執行和間隔循環執行等功能。
2.主要參數
ThreadPoolExecutor是線程池的真正實現,構造方法提供了一系列的參數設置
public ThreadPoolExecutor (int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
corePoolSize:核心線程數量,核心線程指的是即使線程池處於空閒狀態,這些線程也不會被關閉,除非 allowCoreThreadTimeOut設置爲true
maximumPoolSize:最大線程數量,線程池中允許的最大線程數。
keepAliveTime:線程空閒存活時間,當某一非核心線程空閒時,超過這個時間,會被自動回收,當allowCoreThreadTimeOut設置爲true時,這個參數也會對核心線程起作用。
unit:超時時間單位;枚舉量
workQueue:任務阻塞隊列,當且僅當執行了execute()方法後,任務纔會被放入該隊列,然後按照既有的任務策略執行任務。
threadFactory:線程工廠,用來創建新的線程。
handler:任務由於某些原因被拒絕後的處理策略Handler。當任務隊列已滿或者任務無法執行時,這個時候RejectedExecutionHandler就會通知調用者。默認情況下,RejectedExecutionHandler會拋出一個RejectionExecutionException。該量可以通過方法setRejectedExecutionHandler()來設置。有一下幾個之可以提供:
-
ThreadPoolExecutor.AbortPolicy:默認取值,直接拋出RejectionExecutionException;
-
ThreadPoolExecutor.CallerRunsPolicy:交給執行execute()方法的線程執行這個任務;如果線程池已經shudown,這個任務就會被拋棄;
-
ThreadPoolExecutor.DiscardOldestPolicy:拋棄之前的未被執行的任務,重新嘗試execute()方法;如果線程池已經shudown,這個任務就會被拋棄;
-
ThreadPoolExecutor.DiscardPolicy:直接拋棄該任務。
線程池執行任務時大致遵循下列原則:
- 如果線程數量未達到最大核心數量,則直接開啓一個核心線程執行任務;
- 如果線程數量已經達到或者超過最大核心線程,那麼將該任務放入等待隊列workQueue;
- 如果上一步中無法插入到等待隊列,並且線程數量沒有達到最大線程數,那麼開啓一個非核心線程來執行任務;
- 如果已經達到最大線程數,執行RejectionExectionHandler。
3.主要方法
一些set與get方法就不介紹了,這裏主要介紹幾個重要的。
public void allowCoreThreadTimeOut (boolean value):設置核心線程超時,如果設置爲true,核心線程空閒時間超過keepAliveTime會被回收;
protected void beforeExecute (Thread t, Runnable r):線程池中執行任務之前運行的方法,主要用來記錄蒐集數據;
protected void afterExecute (Runnable r, Throwable t):執行任務之後運行的方法
public void purge ():移除等待隊列中已經被cancel的任務;
4.線程分類
Android中常見的四類線程池具有不同的功能,通過對參數進行不同的配置來實現自己的功能特性。
(1)FixedThreadPool
通過執行Executors中的靜態方法newFixedThreadPool方法來獲得,它是一種固定線程數量的線程池,線程空閒也不會回收,除非線程關閉。當所有的線程都處於活動狀態時,新任務會被放入等待隊列,直到有線程空出。由於這些線程不會被收回,因此可以更加快速的響應外界的請求。實現如下:
(2)CachedThreadPool
通過執行Executors中的靜態方法newCachedThreadPool方法來獲得,其實現如下:
從實現方法來看,CachedThreadPool沒有核心線程,線程數量沒有限制,任何線程空閒超過60s就會被回收。該特性表明CachedThreadPool適合執行大量的耗時較少的任務。當沒有任務執行時,其基本上不佔資源。
(3)ScheduledThreadPool
通過執行Executors中的靜態方法newScheduledThreadPool()獲得,其實現如下
其核心線程數量固定,非核心線程沒有限制,非核心線程空閒時立即回收,該線程池可以可以執行延時任務和週期性任務。
(4)SingleThreadScheduledExecutor
通過Executors中的靜態方法newSingleThreadScheduledExecutor()獲得,其實現如下:
核心線程數與最大線程數均爲1,確保所有的任務都在同一個線程中運行,作用在與將外界所有的任務都放在同一個線程中,無需再考慮線程同步的問題。