Android官方开发文档Training系列课程中文版:线程执行操作之创建多线程管理器
原文地址:http://android.xsoftlab.net/training/multiple-threads/create-threadpool.html
上節(jié)課我們學(xué)習(xí)了如何定義一個任務(wù)。如果只是執(zhí)行單次任務(wù),那么剛剛所學(xué)的已經(jīng)基本滿足要求了。如果需要針對不同的數(shù)據(jù)執(zhí)行同種任務(wù),并且需要同一時間只能執(zhí)行一項任務(wù),那么IntentService可能會適合你。如果要使任務(wù)隨著資源的可用而執(zhí)行,或者同一時間需要運行多個任務(wù),那么就需要專門管理這些線程了。Android系統(tǒng)為此提供了一個類,那就是傳說中的ThreadPoolExecutor。它可以在線程可用時自動運行隊列中的任務(wù)。如果要運行一個任務(wù),只需要將任務(wù)添加到隊列中即可。
ThreadPoolExecutor允許多個線程同時進行,所以應(yīng)當(dāng)確保代碼是線程安全的。要確保可能會被多個線程訪問到的變量被放在同步代碼塊中。這種方法可以防止一個線程正在讀取一個變量的值,而另一個變量正在對這個變量寫入新值的現(xiàn)象出現(xiàn)。通常情況下,這種現(xiàn)象會發(fā)生在靜態(tài)變量中,但是也會發(fā)生在單例對象上。
定義線程池類
在該類內(nèi)實例化一個ThreadPoolExecutor對象,并在該類內(nèi)執(zhí)行以下工作:
對線程池對象使用靜態(tài)變量引用
在APP內(nèi)通常只需要一個線程池對象的存在:為了對CPU資源或網(wǎng)絡(luò)資源有一個單一的控制。如果含有不同的Runnable類型,你可能希望對每種類型都創(chuàng)建一個單獨線程池,但是每種類型都還是單例類型。在這里的例子中,可以添加以下代碼作為全局屬性聲明。
public class PhotoManager {...static {...// Creates a single static instance of PhotoManagersInstance = new PhotoManager();}...使用私有構(gòu)造方法:
私有的構(gòu)造方法可以確保該類只有一個對象存在。
調(diào)用線程池的相關(guān)方法啟動任務(wù):
public class PhotoManager { ... // Called by the PhotoView to get a photo static public PhotoTask startDownload(PhotoView imageView,boolean cacheFlag) {...// Adds a download task to the thread pool for executionsInstance.mDownloadThreadPool.execute(downloadTask.getHTTPDownloadRunnable());... }
在線程池類內(nèi)定義一個可以向線程池隊列中添加任務(wù)的方法。在構(gòu)造方法中實例化一個Handler對象,并將其連接到UI線程:Handler允許安全的調(diào)用比如View這種UI對象。大多數(shù)的UI對象只允許被UI線程訪問。
private PhotoManager() { ...// Defines a Handler object that's attached to the UI threadmHandler = new Handler(Looper.getMainLooper()) {/** handleMessage() defines the operations to perform when* the Handler receives a new Message to process.*/@Overridepublic void handleMessage(Message inputMessage) {...}...} }
確定線程池參數(shù)
如果要實例化ThreadPoolExecutor對象,需要用到以下值:
線程池的初始值以及最大值:
- 線程數(shù)量的初始值用于指定池子的初始大小,最大值代表了該線程池所允許開放的最大并發(fā)數(shù)量。線程池中的線程數(shù)量取決于設(shè)備的可用核心數(shù)。這個值與當(dāng)前的設(shè)備頗有關(guān)系:
這個值可能不能夠反映設(shè)備的物理核心數(shù)量;在一些設(shè)備上,核心是否可用取決于系統(tǒng)是否加載。對于這些設(shè)備,availableProcessors()返回了當(dāng)前的活躍核心數(shù)量,這個值可能要比真實的總核心數(shù)要低。
存活時長及單位
- 線程在被關(guān)閉之間的閑置時長。這個時長由時間單元值負責(zé)解釋,這些時間單位常量被定義在類TimeUnit中。
任務(wù)隊列
- 一個持有Runnable對象的隊列。為了啟動線程中的執(zhí)行代碼,線程池管理器采用了先進先出的管理原則。在創(chuàng)建線程池之前需要提供一個這樣的隊列,使用任何實現(xiàn)了BlockingQueue接口的類皆可。為了匹配到APP的要求,你可以選擇適當(dāng)?shù)年犃袑崿F(xiàn);學(xué)習(xí)更多它們的相關(guān)知識,請參見ThreadPoolExecutor的描述文檔。這里的使用了LinkedBlockingQueue:
線程池創(chuàng)建
創(chuàng)建一個線程池,只需調(diào)用ThreadPoolExecutor()實例化一個線程池管理器就好。它會創(chuàng)建并管理一組線程。因為線程池大小的初始值與最大值是相同的,所以ThreadPoolExecutor()會在初始化的時候創(chuàng)建出所指定的線程數(shù)量:
private PhotoManager() {...// Sets the amount of time an idle thread waits before terminatingprivate static final int KEEP_ALIVE_TIME = 1;// Sets the Time Unit to secondsprivate static final TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;// Creates a thread pool managermDecodeThreadPool = new ThreadPoolExecutor(NUMBER_OF_CORES, // Initial pool sizeNUMBER_OF_CORES, // Max pool sizeKEEP_ALIVE_TIME,KEEP_ALIVE_TIME_UNIT,mDecodeWorkQueue);}總結(jié)
以上是生活随笔為你收集整理的Android官方开发文档Training系列课程中文版:线程执行操作之创建多线程管理器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 新媒体中的MCN机构是什么意思
- 下一篇: android sina oauth2.