android 多線程—Handle機(jī)制

線程:是系統(tǒng)進(jìn)行運(yùn)算調(diào)度的最小單位

進(jìn)程:是線程的容器喉刘,是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位,一個(gè)進(jìn)程可以并發(fā)多個(gè)線程

在Android中,系統(tǒng)啟動(dòng)時(shí)默認(rèn)創(chuàng)建主線程,但是主線程(UI線程)不能進(jìn)行耗時(shí)操作懈玻,否則android程序會(huì)無(wú)響應(yīng),所以當(dāng)有耗時(shí)等操作的時(shí)候就可以創(chuàng)建一個(gè)子線程乾颁。

使用線程的優(yōu)點(diǎn):

1.資源利用率更高

例如從磁盤讀取文件的時(shí)候涂乌,讀取一個(gè)文件5s艺栈,處理一個(gè)文件2s,當(dāng)需要讀取2個(gè)文件骂倘,但只有一個(gè)單線程的時(shí)候眼滤,他就會(huì)順序去執(zhí)行,先讀取A并處理完A文件的時(shí)候历涝,才回去讀取B诅需,這樣花費(fèi)的時(shí)間需要14s,但是CPU時(shí)間還有很多空閑荧库。當(dāng)使用兩個(gè)線程時(shí)堰塌,就能讀取完A后,同時(shí)開(kāi)始處理A和讀取B文件的操作分衫,這時(shí)候CPU時(shí)間使用更多场刑,最終花費(fèi)時(shí)間只需要12s

2.程序響應(yīng)更快

例如一個(gè)人服務(wù)器程序是單線程的,此時(shí)如果一個(gè)請(qǐng)求需要占用大量的時(shí)間在這段時(shí)間內(nèi)新的客戶端就無(wú)法發(fā)送請(qǐng)求給服務(wù)器端蚪战,如果引入多線程則會(huì)大大提高效率牵现。

從一個(gè)單線程的應(yīng)用到多線程的應(yīng)用并不僅僅帶來(lái)好處,其也會(huì)帶來(lái)一些代價(jià)邀桑,不要僅僅為了使用多線程而使用多線程瞎疼,應(yīng)該明確在使用多線程的時(shí)候能帶來(lái)的好處比付出的代價(jià)大的時(shí)候,才使用多線程壁畸。

但是有優(yōu)點(diǎn)贼急,當(dāng)然也有缺點(diǎn),現(xiàn)在介紹一下缺點(diǎn)捏萍。

使用線程的缺點(diǎn):

1.等候共享資源會(huì)變慢:

當(dāng)兩個(gè)線程同時(shí)需要使用一個(gè)資源的時(shí)候太抓,就會(huì)出現(xiàn)占用,降低運(yùn)行時(shí)間

2.對(duì)線程管理產(chǎn)生額外的開(kāi)銷:

程的使用會(huì)給系統(tǒng)帶來(lái)上下文切換的額外負(fù)擔(dān)令杈。當(dāng)這種負(fù)擔(dān)超過(guò)一定程度時(shí),多線程的特點(diǎn)主要表現(xiàn)在其缺點(diǎn)上,比如用獨(dú)立的線程來(lái)更新數(shù)組內(nèi)每個(gè)元素走敌。

3.線程的死鎖。即較長(zhǎng)時(shí)間的等待或資源競(jìng)爭(zhēng)以及死鎖等多線程癥狀逗噩。

4.對(duì)公有變量的同時(shí)讀或?qū)懙衾觥.?dāng)多個(gè)線程需要對(duì)公有變量進(jìn)行寫操作時(shí),后一個(gè)線程往往會(huì)修改掉前一個(gè)線程存放的數(shù)據(jù),從而使前一個(gè)線程的參數(shù)被修改;另外 ,當(dāng)公用變量的讀寫操作是非原子性時(shí),在不同的機(jī)器上,中斷時(shí)間的不確定性,會(huì)導(dǎo)致數(shù)據(jù)在一個(gè)線程內(nèi)的操作產(chǎn)生錯(cuò)誤,從而產(chǎn)生莫名其妙的錯(cuò)誤,而這種錯(cuò)誤是程序員無(wú)法預(yù)知的。

當(dāng)然以上的缺點(diǎn)只要涉及合理都是可以避免的

但是設(shè)計(jì)開(kāi)銷會(huì)增加就無(wú)法避免给赞。

android四種常用的操作多線程的方式

1机打、Handle機(jī)制(最常用)

Handle 的一些常用參數(shù)解釋:

Message:消息,就是一個(gè)載體片迅,包含消息ID残邀,消息處理對(duì)象和處理的數(shù)據(jù)等(msg.what ,msg.arg ,msg.obj等).

Handler:用于同一個(gè)進(jìn)程的線程間通信,消息處理者,專門負(fù)責(zé)Message的發(fā)送和處理芥挣。我們使用Handler時(shí)驱闷,一般通過(guò)handleMessage(Message msg)來(lái)處理Message,也就是統(tǒng)一處理消息的回調(diào)空免,確保自己發(fā)出的消息也是自己來(lái)處理空另。

MessageQueue:隊(duì)列,就是存放Handler發(fā)送過(guò)來(lái)的消息蹋砚,按照先進(jìn)先出的順序規(guī)則來(lái)執(zhí)行扼菠。將鏈表的數(shù)據(jù)結(jié)構(gòu)以Message來(lái)串聯(lián)起來(lái),等待Looper的抽取MessageQueue,其他非主線程需要looper的時(shí)候就會(huì)通過(guò)調(diào)用prepare函數(shù)來(lái)實(shí)現(xiàn)坝咐。

Looper:首先要理解一個(gè)線程是一段可執(zhí)行的代碼循榆,作為App的主線程,不能讓代碼執(zhí)行完墨坚,因?yàn)榇a執(zhí)行完的話app就會(huì)自動(dòng)退出秧饮,因此不能讓主線程不能讓代碼段執(zhí)行,只能在代碼中插入一個(gè)死循環(huán)泽篮,這時(shí)候Looper的作用就體現(xiàn)出來(lái)了盗尸,將主線程變成Looper線程。并且這時(shí)主線程就會(huì)在等其他線程發(fā)消息(更新UI和Activity狀態(tài)等等)那帽撑,另外泼各,Looper不斷從消息隊(duì)列拿出消息給主線程,也就是無(wú)限循環(huán)去查找是否有消息油狂,有就去處理历恐,沒(méi)有的話就一直等待寸癌,一個(gè)MessageQueue需要一個(gè)Looper专筷。

Thread:負(fù)責(zé)調(diào)度整個(gè)消息的循環(huán)

怎么利用Handle,讓主線程與子線程通信蒸苇?

答:可以利用HandlerThread進(jìn)行生成一個(gè)子線程的Handler磷蛹,并且實(shí)現(xiàn)handlerMessage方法,然后在主線程里面也生成一個(gè)Handler溪烤,然后通過(guò)調(diào)用sendMessage方法進(jìn)行通知子線程味咳。同樣,子線程里面也可以調(diào)用sendMessage方法進(jìn)行通知主線程檬嘀。這樣做的好處比如有些圖片的加載啊槽驶,網(wǎng)絡(luò)的訪問(wèn)啊可能會(huì)比較耗時(shí),所以放到子線程里面做是比較合適的

Handle 實(shí)例

1.創(chuàng)建一個(gè)線程

創(chuàng)建一個(gè)子進(jìn)程鸳兽,并讓其休眠掂铐,模擬執(zhí)行一個(gè)耗時(shí)操作

public class HandleTest extends Thread{

? ? //Thread build

? ? private String name; //Thread name

? ? public HandleTest(String name){

? ? ? ? this.name=name;

? ? }

? ? static int i = 5;

? ? public void run(){

? ? ? ? Message msg = new Message();

? ? ? ? try {

? ? ? ? ? ? //sleep set 8000

? ? ? ? ? ? i = 3;

? ? ? ? ? ? sleep(8000);

? ? ? ? ? ? msg.what = 1;

? ? ? ? } catch (InterruptedException e) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? }

? ? }

}

在里面創(chuàng)建一個(gè)整型常量3,當(dāng)結(jié)束的時(shí)候傳出參數(shù),并輸出1333全陨,但是在子線程沒(méi)辦法傳回參數(shù)3爆班,因?yàn)閞un是一個(gè)void返回值,這時(shí)候怎么辦辱姨?

public class HandleTest extends Thread{

? //Thread build

? private String name; //Thread name

? public HandleTest(String name){

? ? ? this.name=name;

? }

? static int i = 5;

? public void run(){

? ? ? //instantiation message

? ? ? Message msg = new Message();

? ? ? try {

? ? ? ? ? //sleep set 8000

? ? ? ? ? i = 3;

? ? ? ? ? sleep(8000);

? ? ? // send messge.what = 1 to handle.message

? ? ? ? ? msg.what = 1;

? ? ? } catch (InterruptedException e) {

? ? ? ? ? e.printStackTrace();

? ? ? }

? }

}

有兩種解決辦法柿菩,判斷msg.what或回調(diào)msg數(shù)據(jù)

2.實(shí)例化handle類,并建立message雨涛,傳遞參數(shù)

在主線程創(chuàng)建一個(gè)handle

static int i = 1;

public void handleMessage(){

? ? //When receiving the msg.what == 1,i = 3;

? ? switch (msg.what) {

? ? ? ? ? ? case 0:

? ? ? ? ? ? ? ? i = 3;

? ? ? ? ? ? ? ? break;

? ? ? ? }

}

通過(guò)判斷回調(diào)msg.what修改參數(shù)枢舶,同時(shí)也可以用msg.args回調(diào)整型參數(shù)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市替久,隨后出現(xiàn)的幾起案子祟辟,更是在濱河造成了極大的恐慌,老刑警劉巖侣肄,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件旧困,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡稼锅,警方通過(guò)查閱死者的電腦和手機(jī)吼具,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)矩距,“玉大人拗盒,你說(shuō)我怎么就攤上這事∽墩” “怎么了陡蝇?”我有些...
    開(kāi)封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)哮肚。 經(jīng)常有香客問(wèn)我登夫,道長(zhǎng),這世上最難降的妖魔是什么允趟? 我笑而不...
    開(kāi)封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任恼策,我火速辦了婚禮,結(jié)果婚禮上潮剪,老公的妹妹穿的比我還像新娘涣楷。我一直安慰自己,他們只是感情好抗碰,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布狮斗。 她就那樣靜靜地躺著,像睡著了一般弧蝇。 火紅的嫁衣襯著肌膚如雪碳褒。 梳的紋絲不亂的頭發(fā)上迄汛,一...
    開(kāi)封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音骤视,去河邊找鬼鞍爱。 笑死,一個(gè)胖子當(dāng)著我的面吹牛专酗,可吹牛的內(nèi)容都是我干的睹逃。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼祷肯,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼沉填!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起佑笋,我...
    開(kāi)封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤翼闹,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后蒋纬,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體猎荠,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年蜀备,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了关摇。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡碾阁,死狀恐怖输虱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情脂凶,我是刑警寧澤宪睹,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站蚕钦,受9級(jí)特大地震影響亭病,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜冠桃,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一命贴、第九天 我趴在偏房一處隱蔽的房頂上張望道宅。 院中可真熱鬧食听,春花似錦、人聲如沸污茵。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)泞当。三九已至迹蛤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背盗飒。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工嚷量, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人逆趣。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓蝶溶,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親宣渗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子抖所,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

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