android中的線程和線程池

操作系統中線程是系統調度的最小單元同時線程也是一種受限的系統資源,線程不可能無限制產生,並且線程的創建和銷燬都會有相應的開銷,當系統中存在大量的線程時,系統會通過時間片輪訓的方式調度每個線程,因此線程不可能做到絕對的並行,一個進程中不可能頻繁的創建和銷燬線程,這樣做是不高效的,因此採用線程池的方式,線程池會緩存一定數量的線程,通過線程池就可以避免因爲頻繁創建和銷燬線程所帶來的系統開銷。

主線程是指進程所擁有的線程,默認情況下一個進程只有一個線程,這個線程就是主線程,主線程用來處理和界面交互相關邏輯。子線程也叫作工作線程,除了主線程之外的都是子線程。

Android中的主線程主要作用是運行四大組件以及處理他們和用戶的交互,而子線程的作用是執行耗時任務。

Android中的線程:AsyncTask、HandlerThread、以及IntentService。

AsyncTask在線程池中執行後臺任務,然後把執行的進度和結果傳遞給主線程並在主線程中更新UI。

四個主要的方法:
onPreExecute:主線程中執行,異步任務開始之前執行,做一些準備工作

doInBancGround:在線程池中執行,用於執行異步任務

onProgressUpdate:在主線程中執行,當後臺任務進度發生改變時此方法會被調用。

onPostExecute:在主線程中執行

AsyncTask具體使用過程中的一些條件限制

1.AsyncTask的類必須在主線程中加載。(ActivityThread的main方法中調用了AsyncTask的init方法)

2.AsyncTask的對象必須自主線程中創建

3.execute方法必須在主線程中調用

4.一個AsyncTask對象只能執行一次,即只能調用一次execute方法,否則會出現運行時異常。

AsyncTask內部有一個靜態的InternalHandler對象,該對象繼承與Handler,用於將執行結果從子線程切換到主線程,因此該Handler要求在主線程中創建。由於靜態類成員會在類加載的時候創建,因此這就要求他的外部類AsyncTask在主線程中加載,否則同一個進程中的AsyncTask就無法進行正常工作。

HandlerThread繼承與Thread,是一種可以使用Handler的Thread,實現原理:在run方法中通過Looper.prepare來創建消息隊列,並通過Looper.loop來開啓消息循環。這樣就可以在Handler中創建Handler了

IntentService是一種特殊的Service,他繼承了Service並且自己是一個抽象類,因此必須創建他的子類才能使用IntentService。IntentService用於執行後臺耗時的任務,當任務執行後會自動停止,同時由於IntentService是服務的原因,它的優先級比單純的線程要高很多(不容易被系統殺死),所以IntentService比較適合執行一些高優先級的後臺任務。

在IntentService的onCreate方法中會創建HandlerThread相關的一些東西並獲取到與之對應的Handler,然後在onStart方法中將接收到的Intent通過Handler發送,該Handler接收到消息後(消息循環機制),會將Intent對象傳遞給onHandleIntent方法,然後皆可以通過不同的Intent對不同的後臺任務進行執行,當onHandleIntent方法執行結束後,IntentService會調用stopSelf(有個id,保證所有消息執行完才終止)方法嘗試終止服務。

線程池帶來的好處:

1.重用線程池中的線程,避免因爲線程的創建和開銷帶來的性能影響

2.能夠有效控制線程池的最大併發數,避免大量的線程之間因爲互相搶佔系統資源而導致阻塞現象

3.能夠有效的對線程進行管理,並提供定時執行以及指定間隔循環執行等功能。

Android中的線程池來源於Executor,他是一個接口,真正的線程池的實現爲ThreadPoolExecutor

ThreadPoolExecutor構造方法的幾個參數:

1.corePoolSize:核心線程數

2.maximumPoolSize:線程池所容納的最大線程數

3.keepAliveTime:非核心線程閒置時的超時時長

4.workQueue:存儲通過線程池的execute方法提交的Runnable對象。

ThreadPoolExecutor執行任務所遵循的原則:

1.如果線程池中的線程數量未達到核心線程的數量沒那麼會直接啓動一個核心線程來執行任務

2.如果線程中的線程數量已經達到或者超過核心線程的數量,那麼任務會被插入到任務隊列中排隊等候執行

3.如果步驟2中無法將任務插入到任務隊列中,這說明任務隊列已滿這個時候如果線程池數量未達到線程池規定的最大數,那麼會立刻啓動一個非核心線程來執行任務

4.如果步驟3中線程數量已經達到線程池規定的最大值,那麼就拒絕執行此任務,ThreadPoolExecutor會調用rejectExecutionHandler的rejectExecution方法通知調用者。

線程池分爲四類:

FixedThreadPool:線程數量固定的線程池:該線程池中只有核心線程並且即使線程處於空閒狀態時,也不會被回收,優先級比較高,能夠快速響應外界請求,並且沒有超時閒置,任務隊列大小也沒有限制。比較適用於對響應速度較高的請求

CachedThreadPool:線程數量不定的線程池,只擁有非核心線程,並且線程最大數爲Integer.MAX_VALUE;並且設有超時機制(60),超時60秒閒置會被回收。比較適用於大量的耗時少的任務

ScheduledThreadPool:核心線程數固定,非核心線程數不固定,並且當非核心線程閒置時會被立即回收,,適用於執行定時任務和具有固定週期的任務。

SingleThreadExecutor:內部只有一個核心線程,確保所有的任務都在同一個線程中執行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章