Android進(jìn)階-線程池

在上一篇文章(為什么要學(xué)習(xí)) AsyncTask 原理 提到了線程池账月,那么現(xiàn)在來學(xué)習(xí)學(xué)習(xí) Android 的線程池澡刹。那么來看看線程池有什么優(yōu)點(diǎn)闲孤,或者說為什么要學(xué)習(xí)線程池。

  • 重用線程池中的線程洞拨,避免了新建和銷毀線程的內(nèi)存開銷扯罐。
  • 能有效線程池的最大并發(fā)數(shù),避免大量的線程之間因互相搶占系統(tǒng)資源而導(dǎo)致阻塞現(xiàn)象烦衣。
  • 能夠?qū)€程進(jìn)行簡單的管理歹河,并提供定時(shí)執(zhí)行以及指定間隔循環(huán)執(zhí)行等功能。

基礎(chǔ)線程池

常用的線程池有挺多的花吟,首先來看看基礎(chǔ)線程池 ThreadPoolExcutor 秸歧,其他常見線程池都是基于 ThreadPoolExcutor 去實(shí)現(xiàn)的。那么我們先從它的構(gòu)造方法入手衅澈。

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             threadFactory, defaultHandler);
    }

參數(shù):corePoolSize
線程池的核心線程數(shù)键菱,默認(rèn)情況下核心線程會一直存在,即便是線程處于閑置狀態(tài)今布。
參數(shù):maximumPoolSize
線程池所能容納的最大線程數(shù)经备,當(dāng)核心線程不夠用時(shí)拭抬,就會開啟非核心線程來處理任務(wù),maximumPoolSize = corePoolSize + 非核心線程數(shù)
參數(shù):keepAliveTime
當(dāng)非核心線程處理完任務(wù)處于閑置閑置狀態(tài)時(shí)侵蒙,如果在一定時(shí)間范圍內(nèi)沒有被重用造虎,就會被銷毀。而 keepAliveTime 就是前面所指的一定時(shí)間范圍纷闺。
參數(shù):unit
有了時(shí)間范圍算凿,當(dāng)然要確定時(shí)間的單位。而這個(gè)參數(shù)就是描述時(shí)間范圍的參數(shù)急但。這是一個(gè)枚舉參數(shù)澎媒,常用的有:
TimeUnit.DAYS
TimeUnit.HOURS
TimeUnit.MINUTES
參數(shù):workQueue
線程池的任務(wù)隊(duì)列,線程池的 excute 方法提交的任務(wù)會進(jìn)入這個(gè)隊(duì)列波桩。
參數(shù):threadFactory
為線程池提供新建線程的方法--> newThread(Runnale r)

ThreadPoolExcutor 執(zhí)行任務(wù)時(shí)大致遵循的規(guī)則:

  1. 如果線程池中的線程數(shù)量還沒達(dá)到核心線程數(shù),則新開啟一個(gè)核心線程來執(zhí)行任務(wù)
  2. 如果已經(jīng)達(dá)到或者超過核心線程的數(shù)量请敦,則會被插入到任務(wù)隊(duì)列中镐躲,等待執(zhí)行
  3. 如果任務(wù)隊(duì)列已滿,則會新開啟一個(gè)非核心線程來執(zhí)行任務(wù)侍筛。
  4. 如果線程數(shù)達(dá)到最大值萤皂,則會拒絕執(zhí)行任務(wù)。

ok,解釋了那么多還不如來 實(shí)踐一下匣椰,下面看看小例子:

mExecutor = new ThreadPoolExecutor(3, 6, 1, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(5));//初始化 mExecutor 

fab.setOnClickListener(new View.OnClickListener() {//設(shè)置一個(gè)點(diǎn)擊事件
    @Override
    public void onClick(View view) {
        num++;
        mExecutor.execute(new MyRunnable(String.valueOf(num)));
        Log.d(TAG, "隊(duì)列中等待執(zhí)行的任務(wù)數(shù): "+String.valueOf(mExecutor.getPoolSize()));
        Log.d(TAG, "執(zhí)行完畢是數(shù)量: "+String.valueOf(mExecutor.getCompletedTaskCount()));
    }
});
        

常用線程池

FixedThreadPool
這是一種只有核心線程的線程池裆熙,線程都不會被回收,而且意味著能更快地響應(yīng)任務(wù)禽笑,并且任務(wù)隊(duì)列也沒有大小限制入录。
FixedThreadPool 實(shí)例化方法:

    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

實(shí)例:

ExecutorService e = Executors.newFixedThreadPool(5);
e.execute(new MyRunnable(String.valueOf(num)));

CachedThreadPool
這是一種線程數(shù)不確定的線程池,由下面的實(shí)例化方法可以看出佳镜,核心線程為0僚稿,非核心線程為 Integer.MAX_VALUE ,這是一個(gè)很大的數(shù)蟀伸。超時(shí)策略為 60 秒蚀同。另外,SynchronousQueue 是一個(gè)無法存儲元素的隊(duì)列啊掏,也就是說蠢络,每當(dāng)有新任務(wù),就會立即開啟一個(gè)線程迟蜜。而如果全部任務(wù)都處理完成刹孔,線程池中也可能存在 0 個(gè)線程的情況。所以小泉,幾乎不占用任何系統(tǒng)資源芦疏。
CachedThreadPool 實(shí)例化方法:

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}

實(shí)例:

ExecutorService e2 = Executors.newCachedThreadPool();
e2.execute(new MyRunnable(String.valueOf(num)));

ScheduledThreadPool
從下面的實(shí)例化方法可以看出冕杠,這是一個(gè)核心線程固定,非核心線程很大很大的一個(gè)線程池酸茴。DEFAULT_KEEPALIVE_MILLIS = 10L分预,也就是說超時(shí)策略為 10 毫秒。
實(shí)例化方法:

public ScheduledThreadPoolExecutor(int corePoolSize) {
    super(corePoolSize, Integer.MAX_VALUE,
          DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
          new DelayedWorkQueue());
}

實(shí)例:

ExecutorService e3 = Executors.newScheduledThreadPool(5);
e3.execute(new MyRunnable(String.valueOf(num)));

SingleThreadPool
從下面的實(shí)例化方法中薪捍,可以看出笼痹,這個(gè)線程池,只有一個(gè)核心線程酪穿。它存在的意義就是確保所有任務(wù)都在同一個(gè)線程執(zhí)行凳干,使得這些任務(wù)不需要處理線程同步的問題。
實(shí)例化方法:

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}

實(shí)例:

ExecutorService e4 = Executors.newSingleThreadExecutor();
e4.execute(new MyRunnable(String.valueOf(num)));

總結(jié)

進(jìn)過一系列的學(xué)習(xí)被济,對于線程池也是有了初步的了解救赐,但是了解歸了解,運(yùn)用到實(shí)際開發(fā)中優(yōu)勢另外一回事只磷。還得多與實(shí)際相結(jié)合经磅。

參考文獻(xiàn):《Android開發(fā)藝術(shù)探索》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市钮追,隨后出現(xiàn)的幾起案子预厌,更是在濱河造成了極大的恐慌,老刑警劉巖元媚,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件轧叽,死亡現(xiàn)場離奇詭異,居然都是意外死亡刊棕,警方通過查閱死者的電腦和手機(jī)炭晒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鞠绰,“玉大人腰埂,你說我怎么就攤上這事◎谂颍” “怎么了屿笼?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長翁巍。 經(jīng)常有香客問我驴一,道長,這世上最難降的妖魔是什么灶壶? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任肝断,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘胸懈。我一直安慰自己担扑,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布趣钱。 她就那樣靜靜地躺著涌献,像睡著了一般。 火紅的嫁衣襯著肌膚如雪首有。 梳的紋絲不亂的頭發(fā)上燕垃,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機(jī)與錄音井联,去河邊找鬼卜壕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛烙常,可吹牛的內(nèi)容都是我干的轴捎。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼蚕脏,長吁一口氣:“原來是場噩夢啊……” “哼轮蜕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蝗锥,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎率触,沒想到半個(gè)月后终议,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡葱蝗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年穴张,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片两曼。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡皂甘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出悼凑,到底是詐尸還是另有隱情偿枕,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布户辫,位于F島的核電站渐夸,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏渔欢。R本人自食惡果不足惜墓塌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧苫幢,春花似錦访诱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至伞梯,卻和暖如春玫氢,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背谜诫。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工漾峡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人喻旷。 一個(gè)月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓生逸,卻偏偏與公主長得像,于是被迫代替她去往敵國和親且预。 傳聞我的和親對象是個(gè)殘疾皇子槽袄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

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