如果你要反復(fù)執(zhí)行一個(gè)任務(wù),用不同的數(shù)據(jù)集(參數(shù)不同),但一次只要一個(gè)執(zhí)行(任務(wù)是單線程的),IntentService符合你的需求。當(dāng)需要在資源可用時(shí)自動(dòng)執(zhí)行任務(wù),或允許多任務(wù)同時(shí)執(zhí)行,你需要一個(gè)線程管理器管理你的線程。ThreadPoolExecutor,會(huì)維護(hù)一個(gè)隊(duì)列,當(dāng)它的線程池有空時(shí),從隊(duì)列里取任務(wù),并執(zhí)行。要運(yùn)行任務(wù),你要做的就是把它加到隊(duì)列里。
線程池可以并聯(lián)運(yùn)行一個(gè)任務(wù)的多個(gè)實(shí)例,所以你要保存代碼線程安全。能被多線程訪問(wèn)的變量需要同步塊.更多信息,見(jiàn)Processes and Threads(http://developer.android.com/guide/components/processes-and-threads.html)
定義線程池類(lèi)
在它自己類(lèi)中實(shí)例ThreadPoolExecutor.在類(lèi)里,如下操作:
為線程池使用static變量
你可能在app里只需要一個(gè)單例的線程池,這是為了統(tǒng)一控制限制CPU或網(wǎng)絡(luò)資源。如果你有不同的Runnable類(lèi)型,你可能想要每種類(lèi)型都有各自的線程池,但這些都可以放到一個(gè)單一的實(shí)例里。比如,你可以把它聲明成全局變量:
使用private構(gòu)造方法
把構(gòu)造方法聲明成private,可以確保單例,這意味著你不需要在同步代碼塊里封裝類(lèi)訪問(wèn)。
調(diào)用線程池類(lèi)里的方法來(lái)開(kāi)始任務(wù)
線程池類(lèi)里定義一個(gè)方法,用來(lái)添加任務(wù)到線程池隊(duì)列,如:
實(shí)例化一個(gè)UI線程的Handler.
Handler用于與UI線程通訊,大多數(shù)UI控件只允許在UI線程修改。
判斷線程池參數(shù)
一旦你有了全部類(lèi)結(jié)構(gòu),你就可以開(kāi)始定義線程池。實(shí)例化一個(gè)線程池對(duì)象,你需要下面的值:
初始池大小,最大池大小。
線程池的線程數(shù)量主要依賴于設(shè)備的CPU核心數(shù).可以從系統(tǒng)環(huán)境中獲取。
這個(gè)數(shù)字可能不能反映出設(shè)備的物理cpu內(nèi)核數(shù)量;某些設(shè)備CPU會(huì)根據(jù)系統(tǒng)負(fù)載自動(dòng)禁用部分內(nèi)核,對(duì)于這些設(shè)備,availableProcessors()返回的是當(dāng)前活躍的內(nèi)核數(shù)量。
保持活躍時(shí)間和時(shí)間單位
一個(gè)進(jìn)程在關(guān)閉前,保持空閑狀態(tài)的時(shí)間(可以復(fù)用進(jìn)程)。時(shí)間單位在TimeUnit里
任務(wù)隊(duì)列
ThreadPoolExecutor的列隊(duì)保存Runnable對(duì)象。在線程中執(zhí)行代碼,線程池管理器會(huì)從一個(gè)FIFO隊(duì)列里取出一個(gè)Runnable對(duì)象,附加到線程里。隊(duì)列實(shí)現(xiàn)BlockingQueue接口,在創(chuàng)建線程池時(shí)提供。你可以從現(xiàn)有實(shí)現(xiàn)中選一個(gè),適應(yīng)你的需求,參見(jiàn)ThreadPoolExecutor。下面是使用LinkedBlockingQueue的例子:
創(chuàng)建線程池
調(diào)用ThreadPoolExecutor()方法初始化線程池。它會(huì)創(chuàng)建管理線程。因?yàn)榫€程池的初始大小和最大池大小是一樣的,ThreadPoolExecutor在初始化時(shí)就創(chuàng)建了所有線程對(duì)象,如:
新聞熱點(diǎn)
疑難解答
圖片精選