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

  • 通過(guò)Process.setThreadPriority()方法來(lái)設(shè)置線程使用的是后臺(tái)運(yùn)行優(yōu)先級(jí)矛物。 這個(gè)方法減少了通過(guò)Runnable創(chuàng)建的線程和和UI線程之間的資源競(jìng)爭(zhēng)。
  • 你還應(yīng)該通過(guò)在Runnable 自身中調(diào)用Thread.currentThread()來(lái)存儲(chǔ)一個(gè)引用到Runnable對(duì)象的線程跪但。
    class PhotoDecodeRunnable implements Runnable {
    // 定義要在這個(gè)任務(wù)中執(zhí)行的代碼
    @Override
    public void run() {
    // 把當(dāng)前的線程變成后臺(tái)執(zhí)行的線程
    android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
    ...
    //在PhotoTask實(shí)例中存儲(chǔ)當(dāng)前線程履羞,以至于這個(gè)實(shí)例能中斷這個(gè)線程
    mPhotoTask.setImageDecodeThread(Thread.currentThread());
    ...
    }
    }
  • 創(chuàng)建多線程管理器
    1. 為線程池使用靜態(tài)變量
      為了有一個(gè)單一控制點(diǎn)用來(lái)限制CPU或涉及網(wǎng)絡(luò)資源的Runnable類型,你可能需要有一個(gè)能管理所有線程的線程池屡久,且每個(gè)線程都會(huì)是單個(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. 通過(guò)調(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對(duì)象(例如 View對(duì)象)的方法浸锨。大多數(shù)UI對(duì)象只能從UI線程安全的代碼中被修改。這個(gè)方法將會(huì)在與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對(duì)象,你需要提供以下數(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)核宇姚,對(duì)于這樣的設(shè)備匈庭,availableProcessors()方法返回的是處于活動(dòng)狀態(tài)的內(nèi)核數(shù)量,可能少于設(shè)備的實(shí)際內(nèi)核總數(shù)浑劳。
  1. 線程保持活動(dòng)狀態(tài)的持續(xù)時(shí)間和時(shí)間單位
    這個(gè)是指線程被關(guān)閉前保持空閑狀態(tài)的持續(xù)時(shí)間阱持。這個(gè)持續(xù)時(shí)間通過(guò)時(shí)間單位值進(jìn)行解譯,是TimeUnit()中定義的常量之一魔熏。
  2. 一個(gè)任務(wù)隊(duì)列
    這個(gè)傳入的隊(duì)列由ThreadPoolExecutor獲取的Runnable對(duì)象組成衷咽。為了執(zhí)行一個(gè)線程中的代碼,一個(gè)線程池管理者從先進(jìn)先出的隊(duì)列中取出一個(gè)Runnable對(duì)象且把它附加到一個(gè)線程蒜绽。當(dāng)你創(chuàng)建線程池時(shí)需要提供一個(gè)隊(duì)列對(duì)象镶骗,這個(gè)隊(duì)列對(duì)象類必須實(shí)現(xiàn)BlockingQueue接口。為了滿足你的APP的需求躲雅,你可以選擇一個(gè)Android SDK中已經(jīng)存在的隊(duì)列實(shí)現(xiàn)類鼎姊。為了學(xué)習(xí)更多相關(guān)的知識(shí),你可以看一下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è)線程池相寇,可以通過(guò)調(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è)線程池管理者對(duì)象,這樣就能創(chuàng)建和管理一組可約束的線程了钮科。如果線程池的初始化大小和最大大小相同唤衫,ThreadPoolExecutor在實(shí)例化的時(shí)候就會(huì)創(chuàng)建所有的線程對(duì)象。例如:
    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)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末跺嗽,一起剝皮案震驚了整個(gè)濱河市战授,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌桨嫁,老刑警劉巖植兰,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異璃吧,居然都是意外死亡楣导,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門畜挨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)筒繁,“玉大人,你說(shuō)我怎么就攤上這事巴元≌庇剑” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵逮刨,是天一觀的道長(zhǎng)呕缭。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么恢总? 我笑而不...
    開封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任迎罗,我火速辦了婚禮,結(jié)果婚禮上片仿,老公的妹妹穿的比我還像新娘纹安。我一直安慰自己,他們只是感情好砂豌,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開白布厢岂。 她就那樣靜靜地躺著,像睡著了一般阳距。 火紅的嫁衣襯著肌膚如雪咪笑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天娄涩,我揣著相機(jī)與錄音,去河邊找鬼映跟。 笑死蓄拣,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的努隙。 我是一名探鬼主播球恤,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼荸镊!你這毒婦竟也來(lái)了咽斧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤躬存,失蹤者是張志新(化名)和其女友劉穎张惹,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體岭洲,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宛逗,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盾剩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片雷激。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖告私,靈堂內(nèi)的尸體忽然破棺而出屎暇,到底是詐尸還是另有隱情,我是刑警寧澤驻粟,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布根悼,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏番挺。R本人自食惡果不足惜唠帝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望玄柏。 院中可真熱鬧襟衰,春花似錦、人聲如沸粪摘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)徘意。三九已至苔悦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間椎咧,已是汗流浹背玖详。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留勤讽,地道東北人蟋座。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像脚牍,于是被迫代替她去往敵國(guó)和親向臀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容