線程任務管理器的目的是為了在系統資源可用時自動運行線程任務或同時執行多個線程任務。Android API提供了ThreadPoolExecutor類,它管理了一個線程池,當線程池中的某個線程可用時它會從任務隊列中取出一個任務來運行,我們需要做的就是把我們要執行的任務放入它的任務隊列中。ThreadPoolExecutor可以同時並行執行一個任務,因此我們必須要確保我們的執行任務是線程安全的。
如何使用ThreadPoolExecutor
在線程任務管理器中實例化ThreadPoolExecutor,並聲明一個靜態引用指向它。盡管線程任務管理器可能需要執行不同類型的線程任務,但管理器本身只需要一個單實例即可,因此我們可以把管理器類定義為單實例類並在靜態初始化塊中進行實例化,下面為一個完整的示例:
public class PhotoManager
{
...
/*
* 獲取系統可用的CPU核數,基於此來對線程池的線程數量進行設置
* 需要注意的是,該值可能並非系統的實際CPU核數,因為某些系統
* 可能會根據系統的負載來動態調整可用的CPU,availableProcessors()
* 方法返回的就是當前活躍的CPU核數,該值可能小於系統總的核數
*/
private static int NUMBER_OF_CORES =
Runtime.getRuntime().availableProcessors();
...
//聲明一個任務隊列
private final BlockingQueue
mDecodeWorkQueue;
...
//設置一個線程可閒置的時間
private static final int KEEP_ALIVE_TIME = 1;
//設置一個線程可閒置的時間的單位
private static final TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
...
static {
...
// 創建線程任務管理器PhotoManager類的靜態單實例
sInstance = new PhotoManager();
}
...
/**
* 在這裡創建任務隊列和線程池
*/
private PhotoManager() {
...
//任務隊列的數據結構為LinkedBlockingQueue,ThreadPoolExecutor從這裡取出
//一個執行任務交給線程池中的一個線程來執行,該隊列通常為一個FIFO先入先出
//的隊列,我們可以使用BlockingQueue接口的任何實現類
mDecodeWorkQueue = new LinkedBlockingQueue();
...
// 創建一個線程池
mDecodeThreadPool = new ThreadPoolExecutor(
NUMBER_OF_CORES, // 線程池的初始線程數量
NUMBER_OF_CORES, // 線程池的最大線程數量
KEEP_ALIVE_TIME,
KEEP_ALIVE_TIME_UNIT,
mDecodeWorkQueue);
...
// 初始化一個Handler對象來處理界面的刷新
mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message inputMessage) {
...
//根據收到的消息來進行界面的刷新
...
}
...
}
}
...
// 線程任務啟動方法
public static PhotoTask startDownload(PhotoView imageView,
boolean cacheFlag) {
...
// 使用線程池來執行線程任務
sInstance.
mDownloadThreadPool.
execute(downloadTask.getHTTPDownloadRunnable());
...
}
}