Android 線程管理——摘自【極客學(xué)院】

  • 通過Process.setThreadPriority()方法來設(shè)置線程使用的是后臺運(yùn)行優(yōu)先級。 這個(gè)方法減少了通過Runnable創(chuàng)建的線程和和UI線程之間的資源競爭。
  • 你還應(yīng)該通過在Runnable 自身中調(diào)用Thread.currentThread()來存儲一個(gè)引用到Runnable對象的線程。
    class PhotoDecodeRunnable implements Runnable {
    // 定義要在這個(gè)任務(wù)中執(zhí)行的代碼
    @Override
    public void run() {
    // 把當(dāng)前的線程變成后臺執(zhí)行的線程
    android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
    ...
    //在PhotoTask實(shí)例中存儲當(dāng)前線程,以至于這個(gè)實(shí)例能中斷這個(gè)線程
    mPhotoTask.setImageDecodeThread(Thread.currentThread());
    ...
    }
    }
  • 創(chuàng)建多線程管理器
    1. 為線程池使用靜態(tài)變量
      為了有一個(gè)單一控制點(diǎn)用來限制CPU或涉及網(wǎng)絡(luò)資源的Runnable類型,你可能需要有一個(gè)能管理所有線程的線程池,且每個(gè)線程都會是單個(gè)實(shí)例。比如,你可以把這個(gè)作為一部分添加到你的全局變量的聲明中去:
      public class PhotoManager {
      ...
      static {
      ...
      // Creates a single static instance of PhotoManager
      sInstance = new PhotoManager();
      }
      ...
  1. *** 使用私有構(gòu)造方法***
    讓構(gòu)造方法私有從而保證這是一個(gè)單例,這意味著你不需要在同步代碼塊(synchronized block)中額外訪問這個(gè)類:
    public class PhotoManager {
    ...
    * Constructs the work queues and thread pools used to download
    * and decode images. Because the constructor is marked private,
    * it's unavailable to other classes, even in the same package.
    */
    private PhotoManager() {
    ...
    }

  2. 通過調(diào)用線程池類里的方法開啟你的任務(wù)
    在線程池類中定義一個(gè)能添加任務(wù)到線程池隊(duì)列的方法。例如:
    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 execution
    sInstance.
    mDownloadThreadPool.
    execute(downloadTask.getHTTPDownloadRunnable());
    ...
    }

  3. 在構(gòu)造方法中實(shí)例化一個(gè)Handler,且將它附加到你APP的UI線程。
    一個(gè)Handler允許你的APP安全地調(diào)用UI對象(例如 View對象)的方法。大多數(shù)UI對象只能從UI線程安全的代碼中被修改。這個(gè)方法將會在與UI線程進(jìn)行通信(Communicate with the UI Thread)這一課中進(jìn)行詳細(xì)的描述。例如:
    private PhotoManager() {
    ...
    // Defines a Handler object that's attached to the UI thread
    mHandler = new Handler(Looper.getMainLooper()) {
    /*
    * handleMessage() defines the operations to perform when
    * the Handler receives a new Message to process.
    */
    @Override
    public void handleMessage(Message inputMessage) {
    ...
    }
    ...
    }
    }

  • 確定線程池的參數(shù)
    一旦有了整體的類結(jié)構(gòu),你可以開始定義線程池了。為了初始化一個(gè)ThreadPoolExecutor對象,你需要提供以下數(shù)值:
    1. 線程池的初始化大小和最大的大小
      這個(gè)是指最初分配給線程池的線程數(shù)量,以及線程池中允許的最大線程數(shù)量。在線程池中擁有的線程數(shù)量主要取決于你的設(shè)備的CPU內(nèi)核數(shù)。
      這個(gè)數(shù)字可以從系統(tǒng)環(huán)境中獲得:
      public class PhotoManager {
      ...
      /*
      * Gets the number of available cores
      * (not always the same as the maximum number of cores)
      */
      private static int NUMBER_OF_CORES =Runtime.getRuntime().availableProcessors();
      }
      這個(gè)數(shù)字可能并不反映設(shè)備的物理核心數(shù)量,因?yàn)橐恍┰O(shè)備根據(jù)系統(tǒng)負(fù)載關(guān)閉了一個(gè)或多個(gè)CPU內(nèi)核,對于這樣的設(shè)備,availableProcessors()方法返回的是處于活動狀態(tài)的內(nèi)核數(shù)量,可能少于設(shè)備的實(shí)際內(nèi)核總數(shù)。
  1. 線程保持活動狀態(tài)的持續(xù)時(shí)間和時(shí)間單位
    這個(gè)是指線程被關(guān)閉前保持空閑狀態(tài)的持續(xù)時(shí)間。這個(gè)持續(xù)時(shí)間通過時(shí)間單位值進(jìn)行解譯,是TimeUnit()中定義的常量之一。
  2. 一個(gè)任務(wù)隊(duì)列
    這個(gè)傳入的隊(duì)列由ThreadPoolExecutor獲取的Runnable對象組成。為了執(zhí)行一個(gè)線程中的代碼,一個(gè)線程池管理者從先進(jìn)先出的隊(duì)列中取出一個(gè)Runnable對象且把它附加到一個(gè)線程。當(dāng)你創(chuàng)建線程池時(shí)需要提供一個(gè)隊(duì)列對象,這個(gè)隊(duì)列對象類必須實(shí)現(xiàn)BlockingQueue接口。為了滿足你的APP的需求,你可以選擇一個(gè)Android SDK中已經(jīng)存在的隊(duì)列實(shí)現(xiàn)類。為了學(xué)習(xí)更多相關(guān)的知識,你可以看一下ThreadPoolExecutor類的概述。下面是一個(gè)使用LinkedBlockingQueue實(shí)現(xiàn)的例子:
    public class PhotoManager {
    ...
    private PhotoManager() {
    ...
    // A queue of Runnables
    private final BlockingQueue<Runnable> mDecodeWorkQueue;
    ...
    // Instantiates the queue of Runnables as a LinkedBlockingQueue
    mDecodeWorkQueue = new LinkedBlockingQueue<Runnable>();
    ...
    }
    ...
    }
    創(chuàng)建一個(gè)線程池
    為了創(chuàng)建一個(gè)線程池,可以通過調(diào)用[ThreadPoolExecutor()](http://developer.android.com/reference/java/util/concurrent/ThreadPoolExecutor.html#ThreadPoolExecutor(int, int, long, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue<java.lang.Runnable>))構(gòu)造方法初始化一個(gè)線程池管理者對象,這樣就能創(chuàng)建和管理一組可約束的線程了。如果線程池的初始化大小和最大大小相同,ThreadPoolExecutor在實(shí)例化的時(shí)候就會創(chuàng)建所有的線程對象。例如:
    private PhotoManager() {
    ...
    // Sets the amount of time an idle thread waits before terminating
    private static final int KEEP_ALIVE_TIME = 1;
    // Sets the Time Unit to seconds
    private static final TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
    // Creates a thread pool manager
    mDecodeThreadPool = new ThreadPoolExecutor(
    NUMBER_OF_CORES, // Initial pool size
    NUMBER_OF_CORES, // Max pool size
    KEEP_ALIVE_TIME,
    KEEP_ALIVE_TIME_UNIT,
    mDecodeWorkQueue);
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • 簡介 1. 線程分類 主線程(UI線程) : 處理和界面相關(guān)的事情. 子線程 : 處理耗時(shí)操作. Android中...
    王世軍Steven閱讀 974評論 0 2
  • 第三章 Java內(nèi)存模型 3.1 Java內(nèi)存模型的基礎(chǔ) 通信在共享內(nèi)存的模型里,通過寫-讀內(nèi)存中的公共狀態(tài)進(jìn)行隱...
    澤毛閱讀 4,493評論 2 21
  • 前言 JDK中為我們提供了一個(gè)并發(fā)線程框架,它是的我們可以在有異步任務(wù)或大量并發(fā)任務(wù)需要執(zhí)行時(shí)可以使用它提供的線程...
    Justlearn閱讀 1,901評論 0 10
  • ubuntu14.04設(shè)置靜態(tài)ip 找到文件并作如下修改:sudo vim /etc/network/interf...
    燕京博士閱讀 412評論 0 0

友情鏈接更多精彩內(nèi)容