亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

淺談Android 的線程和線程池的使用

 更新時間:2017年08月31日 09:08:29   作者:wuzhaohui026  
本篇文章主要介紹了淺談Android 的線程和線程池,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

Android 的線程和線程池

從用途上分,線程分為主線程和子線程;主線程主要處理和界面相關(guān)的事情,子線程則往往用于耗時操作。

主線程和子線程

主線程是指進程所擁有的線程。Android 中主線程交 UI 線程,主要作用是運行四大組件以及處理它們和用戶的交互;子線程的作業(yè)則是執(zhí)行耗時任務(wù)。

Android 中的線程形態(tài)

1、AsyncTask AsyncTask 是一種輕量級的異步任務(wù)類,可以在線程池中執(zhí)行后臺任務(wù),然后把執(zhí)行的進度和最終結(jié)果傳遞給主線程并在主線程中更新 UI, AsyncTask 是一個抽象的泛型類,提供了 Params(參數(shù)的類型)、Progress(后臺任務(wù)執(zhí)行進度的類型) 和 Result(后臺任務(wù)的返回結(jié)果的類型) 這三個泛型參數(shù), AsyncTask 提供了4個核心方法

  • onPreExcute(),在主線程中執(zhí)行,在異步任務(wù)執(zhí)行之前,此方法會被調(diào)用,一般可以用于做一些準(zhǔn)備工作。
  • doInBackground(Params...params),在線程池中執(zhí)行,此方法用于執(zhí)行異步任務(wù),params 參數(shù)表示異步任務(wù)的輸入?yún)?shù)。在此方法中可以通過 publishProgress 方法來更新任務(wù)的進度,publishProgress 方法會調(diào)用 onProgressUpdate 方法,另外此方法需要返回計算結(jié)果給 onPostExecute 方法。
  • onProgressUpdate(Progress...values),在主線程中執(zhí)行,當(dāng)后臺任務(wù)的執(zhí)行進度發(fā)生改變時此方法會被調(diào)用。
  • onPostExecute(Resukt result),在主線程中執(zhí)行,在異步任務(wù)執(zhí)行之后,此方法會被調(diào)用,其中 result 參數(shù)是后臺任務(wù)的返回值,即 doInBackground 的返回值。

onPreExcute 先執(zhí)行,接著是 doInBackground,最后才是 onPostExecute。 當(dāng)異步任務(wù)被取消時,onCancelled() 方法會被調(diào)用,這個時候 onPostExecute 則不會被調(diào)用。

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

  • AsyncTask 的類必須在主線程中加載;
  • AsyncTask 的對象必須在 UI 線程中創(chuàng)建;
  • 不要在程序中直接調(diào)用 onPreExecute、onPostExecute、doInBackground 和 onProgressUpdate 方法。
  • 一個 AsyncTask 對象只能執(zhí)行一次,即只能調(diào)用一次 execute 方法,否則會報運行時異常。
  • 在 Android 1.6之前,AsyncTask 是串行執(zhí)行任務(wù)的,Android 1.6的時候 AsyncTask 開始采用線程池處理并行任務(wù),但是從 Android 3.0開始為了避免 AsyncTask 所帶來的并發(fā)錯誤,AsyncTask 又采用一個線程來串行執(zhí)行任務(wù)。但是在 Android 3.0 以及后續(xù)的版本中,仍然可以通過 AsyncTask 的 executeOnExecutor 方法來并行地執(zhí)行任務(wù)。

3、AsyncTask 的工作原理 AsyncTask 中有兩個線程池(SerialExecutor 和 THREAD_POOL_EXECUTOR) 和一個 Handler(InternalHandler),線程池 SerialExecutor 用于任務(wù)的排隊,線程池 THREAD_POOL_EXECUTOR 用于真正地執(zhí)行任務(wù),InternalHandler 用于將執(zhí)行環(huán)境從線程池切換到主線程。

4、HandlerThread HandlerThread 繼承了 Thread,是一種可以使用 Handler 的 Thread, 它的實現(xiàn)就是在 run 方法中通過 Looper.prepare() 來創(chuàng)建消息隊列,并通過 Looper.loop() 來開啟消息循環(huán)。

與普通的 Thread 相比,普通 Thread 主要用于在 run 方法中執(zhí)行一個耗時任務(wù),而 HandlerThread 在內(nèi)部創(chuàng)建了消息隊列,外界需要通過 Handler 的消息方式來通知 HandlerThread 執(zhí)行一個具體的任務(wù)。

由于 HandlerThread 的 run 方法是一個無限循環(huán),因此當(dāng)明確不需要在使用 HandlerThread 時,可以通過它的 quit 或者 quitSafely 方法來終止線程的執(zhí)行。

5、IntentService IntentService 是一種特殊的 Service,繼承了 Service 并且是一個抽象類,必須創(chuàng)建它的子類才能使用 IntentService。IntentService可用于執(zhí)行后臺耗時任務(wù),任務(wù)執(zhí)行后會自動停止,并且它的優(yōu)先級比單純的線程要高很多,不容易被系統(tǒng)殺死。在實現(xiàn)上,IntentService 封裝了 HandlerThread 和 Handler。

Android 中的線程池

線程池的優(yōu)點

  • 重用線程池中的線程,避免因為線程的創(chuàng)建和銷毀所帶來的性能開銷;
  • 能有效控制線程池的最大并發(fā)數(shù),避免大量的線程之間因互相搶占系統(tǒng)資源而導(dǎo)致的阻塞現(xiàn)象;
  • 能夠?qū)€程進行簡單的管理,并提供定時執(zhí)行以及指定間隔循環(huán)執(zhí)行等功能。

ThreadPoolExecutor ThreadPoolExecutor 是線程的真正實現(xiàn)。

public ThreadPoolExecutor(int corePoolSize,
              int maximumPoolSize,
              long keepAliveTime,
              TimeUnit unit,
              BlockingQueue<Runnable> workQueue,
              ThreadFactory threadFactory)
  • corePoolSize 線程池的核心線程數(shù),默認(rèn)情況下,核心線程會在線程池中一直存活,及時處于閑置狀態(tài)。
  • maximumPoolSize 線程池所能容納的最大線程數(shù),當(dāng)活動線程數(shù)達到這個數(shù)值后,后續(xù)的新任務(wù)將會被阻塞。
  • keepAliveTime 非核心線程閑置時的超時時長,超過這個時長,非核心線程就會被回收。
  • unit 用于指定 keepAliveTime 參數(shù)的時間單位,這是一個枚舉,常用的有 TimeUnit、MILLSECONDS(毫秒)、TimeUnit.SECONDS(秒) 以及 TimeUnit.MINUTES(分鐘)。
  • workQueue 線程池中的任務(wù)隊列,通過線程池的 execute 方法提交的 Runnable 對象會存儲在這個參數(shù)中。
  • threadFactory 線程工廠,為線程池通過創(chuàng)建新線程的功能。ThreadFactory 是一個接口,只有 一個方法:Thread newThread(Runnable r)。

ThreadPoolExecutor 執(zhí)行任務(wù)時遵循的規(guī)則

  • 如果線程池中的線程數(shù)量未達到核心線程的數(shù)量,那么會直接啟動一個核心線程來執(zhí)行任務(wù);
  • 如果線程池中的線程數(shù)量已經(jīng)達到或者超過核心線程的數(shù)量,那么任務(wù)會被插入到任務(wù)隊列中排隊等待執(zhí)行;
  • 如果在步驟2中無法將任務(wù)插入到任務(wù)隊列中,這往往是由于任務(wù)隊列已滿,這個時候如果線程數(shù)量為達到線程池規(guī)定的最大值,那么會立刻啟動一個非核心線程來執(zhí)行任務(wù)。
  • 如果步驟3中線程數(shù)量已經(jīng)達到線程池規(guī)定的最大值,那么就拒絕執(zhí)行此任務(wù), ThreadPoolExecutor 會調(diào)用 RejectedExecutionHandler 的 rejectedExecution 方法來通知調(diào)用者。

線程池的分類

  • FixedThreadPool 通過 Executors 的 newFixedThreadPool 方法來創(chuàng)建。是一種線程數(shù)量固定的線程池,當(dāng)線程處于空閑狀態(tài)時并不會被回收,除非線程池被關(guān)閉。FixedThreadPool 中只有核心線程并且這些核心線程沒有超時機制,另外任務(wù)隊列也是沒有大小限制。
  • CachedThreadPool 通過 Executors 的 newCachedThreadPool 方法來創(chuàng)建。是一種線程數(shù)量不定的線程池,只有非核心線程,最大線程數(shù)為 Integer.MAX_VALUE。線程池中的空閑線程都有超時機制,這個超時時長為60秒,超過60秒閑置線程就會被回收。CachedThreadPool 的任務(wù)隊列相當(dāng)于一個空集合,這樣會導(dǎo)致任何任務(wù)都會被立即執(zhí)行。
  • ScheduledThreadPool 通過 Executors 的 newScheduledThreadPool 方法來創(chuàng)建。它的核心線程數(shù)量是固定的,而非核心線程數(shù)是沒有限制的,并且當(dāng)非核心線程閑置時會被立即回收。ScheduledThreadPool 這類線程池主要用于執(zhí)行定時任務(wù)和具有固定周期的重復(fù)任務(wù)。
  • SingleThreadExecutor 通過 Executors 的 newSingleThreadExecutor 方法來創(chuàng)建。這類線程池內(nèi)部只有一個核心線程,它確保所有的任務(wù)都在同一個線程中按順序執(zhí)行。SingleThreadExecutor 的意義在于統(tǒng)一所有的外界任務(wù)到一個線程中,這使得在這些任務(wù)之間不需要處理線程同步的問題。

系統(tǒng)預(yù)置4種線程池的典型使用方法:

Runnable command = new Runnable(){
    @Override
    public void run(){
      SystemClock.sleep(2000);
    }

  ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
  fixedThreadPool.execute(command);

  ExecutorService cachedThreadPool =Executors.newCachedThreadPool();
  cachedThreadPool.execute(command);

  ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4);
  // 2000ms 后執(zhí)行 command
  scheduledThreadPool.schedule(command,2000,TimeUnit.MILLISECONDS);
  // 延遲10ms,每個1000ms執(zhí)行一次 command
  scheduledThreadPool.scheduleAtFixedRate(command,10,1000,TimeUnit.MILLISECONDS);

  ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
  singleThreadExecutor.execute(command);

  }

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論