Android線(xiàn)程池學(xué)習(xí)總結(jié)

之前的項(xiàng)目中一直沒(méi)有用到線(xiàn)程池畜号,對(duì)這個(gè)概念也不太熟悉帚呼,最近看書(shū)的時(shí)候看到線(xiàn)程池绍移,學(xué)習(xí)了它在Android中的應(yīng)用,來(lái)總結(jié)記錄一下急凰。

線(xiàn)程池:線(xiàn)程池是一個(gè)對(duì)象池(String也有一個(gè)字符串對(duì)象池女仰,當(dāng)我們用"123"這樣的形式聲明一個(gè)字符串對(duì)象時(shí),jvm會(huì)先在String對(duì)象池中找有沒(méi)有這個(gè)字符串對(duì)象抡锈,如果有疾忍,就將這個(gè)字符串對(duì)象的引用直接返回就可以,如果沒(méi)有床三,就在String對(duì)象池中先創(chuàng)建一個(gè)"123"的字符串對(duì)象)一罩,所有對(duì)象池都有一個(gè)共性,就是最大程度的復(fù)用對(duì)象撇簿,省去了重復(fù)創(chuàng)建聂渊,銷(xiāo)毀對(duì)象的時(shí)間開(kāi)銷(xiāo)。而線(xiàn)程池就是管理線(xiàn)程四瘫,最大程度的利用線(xiàn)程汉嗽。當(dāng)有線(xiàn)程任務(wù)時(shí),從池中取一個(gè)線(xiàn)程來(lái)執(zhí)行任務(wù)找蜜,執(zhí)行結(jié)束之后饼暑,線(xiàn)程對(duì)象歸池。

進(jìn)程和線(xiàn)程:關(guān)于進(jìn)程和線(xiàn)程需要提一下洗做,一個(gè)進(jìn)程可以有多個(gè)線(xiàn)程弓叛,每個(gè)進(jìn)程有獨(dú)立的運(yùn)行空間,而所有的線(xiàn)程共享一片內(nèi)存空間诚纸,而每個(gè)線(xiàn)程有獨(dú)立的椬辏空間也存儲(chǔ)線(xiàn)程執(zhí)行過(guò)程中的數(shù)據(jù)。

線(xiàn)程池的優(yōu)點(diǎn):

  1. 避免頻繁的創(chuàng)建和銷(xiāo)毀線(xiàn)程帶來(lái)的時(shí)間開(kāi)銷(xiāo)畦徘。
  2. 避免多個(gè)線(xiàn)程之間因搶占系統(tǒng)資源導(dǎo)致的線(xiàn)程阻塞毕籽。
  3. 能夠?qū)€(xiàn)程進(jìn)行簡(jiǎn)單的管理抬闯,提供間隔執(zhí)行,定時(shí)執(zhí)行等功能影钉。

子線(xiàn)程和主線(xiàn)程

Android的主線(xiàn)程就是UI線(xiàn)程画髓,UI線(xiàn)程負(fù)責(zé)和用戶(hù)進(jìn)行交互掘剪,保持高度的響應(yīng)平委,所以在主線(xiàn)程中不能加入耗時(shí)操作,避免線(xiàn)程不能及時(shí)響應(yīng)用戶(hù)操作夺谁,出現(xiàn)ANR現(xiàn)象廉赔。而在Android3.0之后,所有的網(wǎng)絡(luò)請(qǐng)求都不允許在主線(xiàn)程執(zhí)行匾鸥,也是因?yàn)檫@個(gè)原因蜡塌。所以我們通常會(huì)開(kāi)啟一個(gè)線(xiàn)程來(lái)執(zhí)行耗時(shí)任務(wù)。

1.子線(xiàn)程和主線(xiàn)程交互問(wèn)題

在子線(xiàn)程從進(jìn)行耗時(shí)任務(wù)勿负,在任務(wù)完成之后需要通知用戶(hù)馏艾,這個(gè)時(shí)候就需要更新UI。Android的UI線(xiàn)程是線(xiàn)程不安全的奴愉,如果想要更新UI琅摩,必須在主線(xiàn)程中進(jìn)行。這個(gè)時(shí)候锭硼,我們可以考慮使用Handler房资。

在子線(xiàn)程中發(fā)送消息,由主線(xiàn)程中的Handler接收檀头,并進(jìn)行消息處理轰异。

注:這里只是簡(jiǎn)單演示一下,實(shí)際開(kāi)發(fā)中的Handler不能這樣寫(xiě)暑始,要寫(xiě)成靜態(tài)匿名內(nèi)部類(lèi)+軟引用的方式搭独,否則很容易引起內(nèi)存泄漏,由于此次的重點(diǎn)不在這里廊镜,就不詳細(xì)說(shuō)了牙肝,貼一篇我看過(guò)的文章,這里寫(xiě)的很詳細(xì)期升,感興趣的可以看一下惊奇,Android 內(nèi)存泄露總結(jié) .

//主線(xiàn)程中
private Handler handler = new Handler() {
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case UPDATE_TEXT:
                // 在這里可以進(jìn)行UI操作
                text.setText("Nice to meet you");
                break;
            default:
                break;
        }
    }
};


 //子線(xiàn)程中
Message message = new Message();
message.what = UPDATE_TEXT;
handler.sendMessage(message); // 將Message對(duì)象發(fā)送出去
異步消息處理機(jī)制

Android中的異步消息主要由4部分構(gòu)成,Handler播赁,Message颂郎,MessageQueue,Lopper.

Message:在線(xiàn)程之間傳遞的消息容为,內(nèi)部可攜帶少量信息乓序。
Handler:處理和發(fā)送消息寺酪,sendMessage()和handleMessage().
MessageQueue:消息隊(duì)列,用于存放Handler發(fā)送的消息替劈,消息隊(duì)列中的消息等待被處理寄雀,每個(gè)線(xiàn)程只有一個(gè)MessageQueue.
Lopper:線(xiàn)程中的MessageQueue的管家,調(diào)用Lopper的loop()就會(huì)進(jìn)入無(wú)限循環(huán)中陨献,每當(dāng)MessageQueue中有消息盒犹,Looper就會(huì)將它取出,傳遞到Handler的handleMessage()方法中眨业。每個(gè)線(xiàn)程中只有一個(gè)Looper急膀。

經(jīng)過(guò)下面的處理過(guò)程,消息就從子線(xiàn)程回到了主線(xiàn)程中龄捡。

處理過(guò)程

線(xiàn)程池

Java中線(xiàn)程池的頂級(jí)是Excutor卓嫂,而真正的實(shí)現(xiàn)類(lèi)是ExcutorService,ExcutorService的默認(rèn)實(shí)現(xiàn)是ThreadPoolExcutor,可以使用Excutors類(lèi)中的方法自動(dòng)創(chuàng)建線(xiàn)程池聘殖。

Excutors中默認(rèn)實(shí)現(xiàn)的幾種線(xiàn)程:

newCachedThreadPool:返回一個(gè)能根據(jù)實(shí)際情況調(diào)整線(xiàn)程池中線(xiàn)程數(shù)量的線(xiàn)程池晨雳,也就是說(shuō),線(xiàn)程的數(shù)量是不固定的奸腺。調(diào)用 execute() 將重用以前構(gòu)造的線(xiàn)程(如果線(xiàn)程可用)餐禁。如果現(xiàn)有線(xiàn)程沒(méi)有可用的,則創(chuàng)建一個(gè)新線(xiàn)程并添加到池中洋机,去處理新任務(wù)坠宴。終止并從緩存中移除那些已有 60 秒鐘未被使用的線(xiàn)程(60s是該線(xiàn)程的默認(rèn)“保持活動(dòng)時(shí)間”)。因此绷旗,長(zhǎng)時(shí)間保持空閑的線(xiàn)程池不會(huì)使用任何資源喜鼓。注意,可以使用 ThreadPoolExecutor 構(gòu)造方法創(chuàng)建具有類(lèi)似屬性但細(xì)節(jié)不同(例如超時(shí)參數(shù))的線(xiàn)程池衔肢。

newFixedThreadPool:返回一個(gè)有固定線(xiàn)程數(shù)量的線(xiàn)程池庄岖,每次提交一個(gè)任務(wù)就創(chuàng)建一個(gè)線(xiàn)程,直到線(xiàn)程達(dá)到線(xiàn)程池的最大大小角骤,線(xiàn)程池的大小一旦達(dá)到最大值就會(huì)保持不變隅忿,如果某個(gè)線(xiàn)程因?yàn)閳?zhí)行異常而結(jié)束,那么線(xiàn)程池會(huì)補(bǔ)充一個(gè)新線(xiàn)程邦尊。如果有新任務(wù)提交背桐,但是沒(méi)有空閑線(xiàn)程來(lái)處理,線(xiàn)程數(shù)量已經(jīng)達(dá)到了最大值蝉揍,這時(shí)任務(wù)會(huì)被加入任務(wù)隊(duì)列中链峭,等待空閑線(xiàn)程來(lái)執(zhí)行。

newSingleThreadExecutor:創(chuàng)建是一個(gè)單線(xiàn)程池又沾,也就是該線(xiàn)程池只有一個(gè)線(xiàn)程在工作弊仪,所有的任務(wù)是串行執(zhí)行的熙卡,如果這個(gè)唯一的線(xiàn)程因?yàn)楫惓=Y(jié)束,那么會(huì)有一個(gè)新的線(xiàn)程來(lái)替代它励饵,此線(xiàn)程池保證所有任務(wù)的執(zhí)行順序按照任務(wù)的提交順序執(zhí)行驳癌。該線(xiàn)程池每次只能只執(zhí)行一個(gè)線(xiàn)程任務(wù),多余的任務(wù)放入任務(wù)隊(duì)列役听,等待順序執(zhí)行颓鲜。

newScheduledThreadPool:創(chuàng)建一個(gè)大小無(wú)限的線(xiàn)程池,此線(xiàn)程池支持定時(shí)以及周期性執(zhí)行任務(wù)的需求禾嫉。

ThreadPoolExcutor構(gòu)造函數(shù)灾杰,相關(guān)參數(shù)說(shuō)明:

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

1)corePoolSize:線(xiàn)程池的核心線(xiàn)程數(shù)蚊丐,一般情況下不管有沒(méi)有任務(wù)都會(huì)一直在線(xiàn)程池中一直存活熙参,只有在 ThreadPoolExecutor 中的方法 allowCoreThreadTimeOut(boolean value) 設(shè)置為 true 時(shí),閑置的核心線(xiàn)程會(huì)存在超時(shí)機(jī)制麦备,如果在指定時(shí)間沒(méi)有新任務(wù)來(lái)時(shí)孽椰,核心線(xiàn)程也會(huì)被終止,而這個(gè)時(shí)間間隔由第3個(gè)屬性 keepAliveTime 指定凛篙。

2)maximumPoolSize:線(xiàn)程池所能容納的最大線(xiàn)程數(shù)黍匾,當(dāng)活動(dòng)的線(xiàn)程數(shù)達(dá)到這個(gè)值后,后續(xù)的新任務(wù)將會(huì)被阻塞呛梆。

3)keepAliveTime:控制線(xiàn)程閑置時(shí)的超時(shí)時(shí)長(zhǎng)锐涯,超過(guò)則終止該線(xiàn)程。一般情況下用于非核心線(xiàn)程填物,只有在ThreadPoolExecutor 中的方法 allowCoreThreadTimeOut(boolean value) 設(shè)置為 true時(shí)纹腌,也作用于核心線(xiàn)程。

4)unit:用于指定 keepAliveTime 參數(shù)的時(shí)間單位滞磺,TimeUnit 是個(gè) enum 枚舉類(lèi)型升薯,常用的有:TimeUnit.HOURS(小時(shí))、TimeUnit.MINUTES(分鐘)击困、TimeUnit.SECONDS(秒) 和 TimeUnit.MILLISECONDS(毫秒)等涎劈。

5)workQueue:線(xiàn)程池的任務(wù)隊(duì)列,通過(guò)線(xiàn)程池的 execute(Runnable command) 方法會(huì)將任務(wù) Runnable 存儲(chǔ)在隊(duì)列中阅茶。

6)threadFactory:線(xiàn)程工廠(chǎng)蛛枚,它是一個(gè)接口,用來(lái)為線(xiàn)程池創(chuàng)建新線(xiàn)程的脸哀。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蹦浦,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子企蹭,更是在濱河造成了極大的恐慌白筹,老刑警劉巖智末,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異徒河,居然都是意外死亡系馆,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)顽照,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)由蘑,“玉大人,你說(shuō)我怎么就攤上這事代兵∧崮穑” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵植影,是天一觀的道長(zhǎng)裳擎。 經(jīng)常有香客問(wèn)我,道長(zhǎng)思币,這世上最難降的妖魔是什么鹿响? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮谷饿,結(jié)果婚禮上惶我,老公的妹妹穿的比我還像新娘。我一直安慰自己博投,他們只是感情好绸贡,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著毅哗,像睡著了一般听怕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上黎做,一...
    開(kāi)封第一講書(shū)人閱讀 49,816評(píng)論 1 290
  • 那天叉跛,我揣著相機(jī)與錄音,去河邊找鬼蒸殿。 笑死筷厘,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的宏所。 我是一名探鬼主播酥艳,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼爬骤!你這毒婦竟也來(lái)了充石?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤霞玄,失蹤者是張志新(化名)和其女友劉穎骤铃,沒(méi)想到半個(gè)月后拉岁,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡惰爬,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年喊暖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片撕瞧。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡陵叽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出丛版,到底是詐尸還是另有隱情巩掺,我是刑警寧澤,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布页畦,位于F島的核電站胖替,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏寇漫。R本人自食惡果不足惜刊殉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望州胳。 院中可真熱鬧,春花似錦逸月、人聲如沸栓撞。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)瓤湘。三九已至,卻和暖如春恩尾,著一層夾襖步出監(jiān)牢的瞬間弛说,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工翰意, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留木人,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓冀偶,卻偏偏與公主長(zhǎng)得像醒第,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子进鸠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

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