Java基礎(chǔ)之多線程

1.Thread線程

線程中start和run方法有什么區(qū)別砰盐?wait和sleep方法的不同肿仑?sleep() 、join()腥泥、yield()有什么區(qū)別匾南?

答:run()方法:在本線程內(nèi)調(diào)用該Runnable對象的run()方法,可以重復(fù)多次調(diào)用蛔外;

start()方法:啟動一個(gè)線程蛆楞,調(diào)用該Runnable對象的run()方法,不能多次啟動一個(gè)線程冒萄;

wait和sleep方法區(qū)別:

1.sleep 是線程類(Thread)的方法,導(dǎo)致此線程暫停執(zhí)行指定時(shí)間橙数,給執(zhí)行機(jī)會給其他線程尊流,但是監(jiān)控狀態(tài)依然保持,到時(shí)后會自動恢復(fù)灯帮,調(diào)用sleep 不會釋放對象鎖崖技。由于沒有釋放對象鎖逻住,所以不能調(diào)用里面的同步方法。

sleep()使當(dāng)前線程進(jìn)入停滯狀態(tài)(阻塞當(dāng)前線程)迎献,讓出CUP的使用瞎访、目的是不讓當(dāng)前線程獨(dú)自霸占該進(jìn)程所獲的CPU資源,以留一定時(shí)間給其他線程執(zhí)行的機(jī)會;

sleep()是Thread類的Static(靜態(tài))的方法吁恍;因此他不能改變對象的機(jī)鎖扒秸,所以當(dāng)在一個(gè)Synchronized塊中調(diào)用Sleep()方法是,線程雖然休眠了冀瓦,但是對象的機(jī)鎖并木有被釋放伴奥,其他線程無法訪問這個(gè)對象(即使睡著也持有對象鎖)。

在sleep()休眠時(shí)間期滿后翼闽,該線程不一定會立即執(zhí)行拾徙,這是因?yàn)槠渌€程可能正在運(yùn)行而且沒有被調(diào)度為放棄執(zhí)行,除非此線程具有更高的優(yōu)先級感局。

wait()方法是Object類里的方法尼啡;當(dāng)一個(gè)線程執(zhí)行到wait()方法時(shí),它就進(jìn)入到一個(gè)和該對象相關(guān)的等待池中询微,同時(shí)失去(釋放)了對象的機(jī)鎖(暫時(shí)失去機(jī)鎖崖瞭,wait(long timeout)超時(shí)時(shí)間到后還需要返還對象鎖);可以調(diào)用里面的同步方法拓提,其他線程可以訪問读恃;

wait()使用notify或者notifyAlll或者指定睡眠時(shí)間來喚醒當(dāng)前等待池中的線程。

wiat()必須放在synchronized block中代态,否則會在program runtime時(shí)扔出”java.lang.IllegalMonitorStateException“異常

2.sleep必須捕獲異常寺惫,而wait,notify和notifyAll不需要捕獲異常

sleep方法屬于Thread類中方法蹦疑,表示讓一個(gè)線程進(jìn)入睡眠狀態(tài)西雀,等待一定的時(shí)間之后,自動醒來進(jìn)入到可運(yùn)行狀態(tài)歉摧,不會馬上進(jìn)入運(yùn)行狀態(tài)艇肴,因?yàn)榫€程調(diào)度機(jī)制恢復(fù)線程的運(yùn)行也需要時(shí)間,一個(gè)線程對象調(diào)用了sleep方法之后叁温,并不會釋放他所持有的所有對象鎖再悼,所以也就不會影響其他進(jìn)程對象的運(yùn)行。但在sleep的過程中過程中有可能被其他對象調(diào)用它的interrupt(),產(chǎn)生InterruptedException異常膝但,如果你的程序不捕獲這個(gè)異常冲九,線程就會異常終止,進(jìn)入TERMINATED狀態(tài)跟束,如果你的程序捕獲了這個(gè)異常莺奸,那么程序就會繼續(xù)執(zhí)行catch語句塊(可能還有finally語句塊)以及以后的代碼丑孩。

注意sleep()方法是一個(gè)靜態(tài)方法,也就是說他只對當(dāng)前對象有效灭贷,通過t.sleep()讓t對象進(jìn)入sleep温学,這樣的做法是錯(cuò)誤的,它只會是使當(dāng)前線程被sleep 而不是t線程

wait屬于Object的成員方法甚疟,一旦一個(gè)對象調(diào)用了wait方法仗岖,必須要采用notify()和notifyAll()方法喚醒該進(jìn)程;如果線程擁有某個(gè)或某些對象的同步鎖,那么在調(diào)用了wait()后古拴,這個(gè)線程就會釋放它持有的所有同步資源箩帚,而不限于這個(gè)被調(diào)用了wait()方法的對象。wait()方法也同樣會在wait的過程中有可能被其他對象調(diào)用interrupt()方法而產(chǎn)生

3.sleep()是讓某個(gè)線程暫停運(yùn)行一段時(shí)間,其控制范圍是由當(dāng)前線程決定,也就是說,在線程里面決定.好比如說,我要做的事情是 "點(diǎn)火->燒水->煮面",而當(dāng)我點(diǎn)完火之后我不立即燒水,我要休息一段時(shí)間再燒.對于運(yùn)行的主動權(quán)是由我的流程來控制.

而wait(),首先,這是由某個(gè)確定的對象來調(diào)用的,將這個(gè)對象理解成一個(gè)傳話的人,當(dāng)這個(gè)人在某個(gè)線程里面說"暫停!",也是 thisOBJ.wait(),這里的暫停是阻塞,還是"點(diǎn)火->燒水->煮飯",thisOBJ就好比一個(gè)監(jiān)督我的人站在我旁邊,本來該線 程應(yīng)該執(zhí)行1后執(zhí)行2,再執(zhí)行3,而在2處被那個(gè)對象喊暫停,那么我就會一直等在這里而不執(zhí)行3,但正個(gè)流程并沒有結(jié)束,我一直想去煮飯,但還沒被允許, 直到那個(gè)對象在某個(gè)地方說"通知暫停的線程啟動!",也就是thisOBJ.notify()的時(shí)候,那么我就可以煮飯了,這個(gè)被暫停的線程就會從暫停處 繼續(xù)執(zhí)行.

yield方法:暫停當(dāng)前正在執(zhí)行的線程對象黄痪。

yield()只是使當(dāng)前線程重新回到可執(zhí)行狀態(tài)紧帕,所以執(zhí)行yield()的線程有可能在進(jìn)入到可執(zhí)行狀態(tài)后馬上又被執(zhí)行。

yield()只能使同優(yōu)先級或更高優(yōu)先級的線程有執(zhí)行的機(jī)會桅打。?

join方法:等待該線程終止是嗜。

等待調(diào)用join方法的線程結(jié)束,再繼續(xù)執(zhí)行挺尾。如:t.join();//主要用于等待t線程運(yùn)行結(jié)束鹅搪,若無此句,main則會執(zhí)行完畢遭铺,導(dǎo)致結(jié)果不可預(yù)測丽柿。

為什么我們調(diào)用start()方法時(shí)會執(zhí)行run()方法?

答:因?yàn)轭怲hread中的start方法中魂挂,調(diào)用了Thread中的run方法甫题。順便說下,類A繼承了Tread類涂召,在A中寫run方法坠非,就會覆蓋掉Thread中的run方法,所以此時(shí)調(diào)用start方法后果正,實(shí)現(xiàn)的是自己的run方法體里面的代碼炎码。

為什么我們不能直接調(diào)用run()方法?

答:如果我們直接調(diào)用子線程的run()方法秋泳,其方法還是運(yùn)行在主線程中潦闲,代碼在程序中是順序執(zhí)行的,所以不會有解決耗時(shí)操作的問題迫皱。所以不能直接調(diào)用線程的run()方法歉闰,只有子線程開始了,才會有異步的效果。當(dāng)thread.start()方法執(zhí)行了以后新娜,子線程才會執(zhí)行run()方法,這樣的效果和在主線程中直接調(diào)用run()方法的效果是截然不同的既绩。

Java 中如何停止一個(gè)線程概龄?

答:終止線程的三種方法:

1. 使用退出標(biāo)志,使線程正常退出饲握,也就是當(dāng)run方法完成后線程終止私杜。

2. 使用stop方法強(qiáng)行終止線程(這個(gè)方法不推薦使用,因?yàn)閟top和suspend救欧、resume一樣衰粹,也可能發(fā)生不可預(yù)料的結(jié)果)。

3. 使用interrupt方法中斷線程笆怠。

stop() 和 suspend() 方法為何不推薦使用铝耻?

答:stop()方法作為一種粗暴的線程終止行為,在線程終止之前沒有對其做任何的清除操作蹬刷,因此具有固有的不安全性瓢捉。 用Thread.stop()方法來終止線程將會釋放該線程對象已經(jīng)鎖定的所有監(jiān)視器。如果以前受這些監(jiān)視器保護(hù)的任何對象都處于不連貫狀態(tài)办成,那么損壞的對象對其他線程可見泡态,這有可能導(dǎo)致不安全的操作。?由于上述原因迂卢,因此不應(yīng)該使用stop()方法某弦,而應(yīng)該在自己的Thread類中置入一個(gè)標(biāo)志,用于控制目標(biāo)線程是活動還是停止而克。如果該標(biāo)志指示它要停止運(yùn)行靶壮,可使其結(jié)束run()方法。如果目標(biāo)線程等待很長時(shí)間拍摇,則應(yīng)使用interrupt()方法來中斷該等待亮钦。

suspend()方法 該方法已經(jīng)遭到反對,因?yàn)樗哂泄逃械乃梨i傾向充活。調(diào)用suspend()方法的時(shí)候蜂莉,目標(biāo)線程會停下來。如果目標(biāo)線程掛起時(shí)在保護(hù)關(guān)鍵系統(tǒng)資源的監(jiān)視器上保持有鎖混卵,則在目標(biāo)線程重新開始以前映穗,其他線程都不能訪問該資源。除非被掛起的線程恢復(fù)運(yùn)行幕随。對任何其他線程來說蚁滋,如果想恢復(fù)目標(biāo)線程,同時(shí)又試圖使用任何一個(gè)鎖定的資源,就會造成死鎖辕录。由于上述原因睦霎,因此不應(yīng)該使用suspend()方法,而應(yīng)在自己的thread類中置入一個(gè)標(biāo)志走诞,用于控制線程是活動還是掛起副女。如果標(biāo)志指出線程應(yīng)該掛起,那么用wait()方法命令其進(jìn)入等待狀態(tài)蚣旱。如果標(biāo)志指出線程應(yīng)當(dāng)恢復(fù)碑幅,那么用notify()方法重新啟動線程。

2.多線程

說一說多線程原理塞绿,如果線程過多,會怎樣?多線程的優(yōu)點(diǎn)沟涨?同時(shí)多線程的缺點(diǎn)?

答:多線程的原理

同一時(shí)間內(nèi)异吻,CPU只能處理1條線程裹赴,只有1條線程在工作(執(zhí)行);多線程并發(fā)(同時(shí))執(zhí)行,其實(shí)是CPU快速地在多條線程之間調(diào)度(切換)诀浪。如果CPU調(diào)度線程的時(shí)間足夠快篮昧,就造成了多線程并發(fā)執(zhí)行的假象。

多線程的好處:

1.使用線程可以把占據(jù)時(shí)間長的程序中的任務(wù)放到后臺去處理

2.用戶界面更加吸引人,這樣比如用戶點(diǎn)擊了一個(gè)按鈕去觸發(fā)某件事件的處理,可以彈出一個(gè)進(jìn)度條來顯示處理的進(jìn)度

3.程序的運(yùn)行效率可能會提高

4.在一些等待的任務(wù)實(shí)現(xiàn)上如用戶輸入,文件讀取和網(wǎng)絡(luò)收發(fā)數(shù)據(jù)等,線程就比較有用了.

多線程的缺點(diǎn):

1.如果有大量的線程,會影響性能,因?yàn)椴僮飨到y(tǒng)需要在它們之間切換.

2.更多的線程需要更多的內(nèi)存空間

3.線程中止需要考慮對程序運(yùn)行的影響.

4.通常塊模型數(shù)據(jù)是在多個(gè)線程間共享的,需要防止線程死鎖情況的發(fā)生

現(xiàn)在有T1笋妥、T2懊昨、T3三個(gè)線程,你怎樣保證T2在T1執(zhí)行完后執(zhí)行春宣,T3在T2執(zhí)行完后執(zhí)行酵颁?

答:假設(shè)現(xiàn)在有兩個(gè)線程A帆离、B蝌以。如果在A的run方法中調(diào)用B.join(),表示A需要在B線程上面等待框咙,也就是需要在B線程執(zhí)行完成之后才能再次執(zhí)行嚷辅。了解這個(gè)概念之后簿姨,這個(gè)問題就很簡單了,java代碼如下:

Thread t1 = new Thread(new T1());

Thread t2 = new Thread(new T2());

Thread t3 = new Thread(new T3());

t1.start();

t1.join();

t2.start();

t2.join();

t3.start();?

在Java中Lock接口比synchronized塊的優(yōu)勢是什么簸搞?

答:能夠顯示地獲取和釋放鎖扁位,鎖的運(yùn)用更靈活

可以方便地實(shí)現(xiàn)公平鎖

能夠響應(yīng)中斷,非阻塞獲取鎖

3.線程池

線程池的關(guān)閉方式有幾種趁俊,各自的區(qū)別是什么域仇?線程池中submit() 和 execute()方法有什么區(qū)別?

答:我們知道寺擂,使用shutdownNow方法暇务,可能會引起報(bào)錯(cuò)泼掠,使用shutdown方法可能會導(dǎo)致線程關(guān)閉不了。

所以當(dāng)我們使用shutdownNow方法關(guān)閉線程池時(shí)垦细,一定要對任務(wù)里進(jìn)行異常捕獲择镇。

當(dāng)我們使用shuwdown方法關(guān)閉線程池時(shí),一定要確保任務(wù)里不會有永久阻塞等待的邏輯括改,否則線程池就關(guān)閉不了沐鼠。

最后,一定要記得叹谁,shutdownNow和shuwdown調(diào)用完,線程池并不是立馬就關(guān)閉了乘盖,要想等待線程池關(guān)閉焰檩,還需調(diào)用awaitTermination方法來阻塞等待。

1订框、接收的參數(shù)不一樣

2析苫、submit有返回值,而execute沒有

用到返回值的例子穿扳,比如說我有很多個(gè)做validation的task衩侥,我希望所有的task執(zhí)行完,然后每個(gè)task告訴我它的執(zhí)行結(jié)果矛物,是成功還是失敗茫死,如果是失敗,原因是什么履羞。

然后我就可以把所有失敗的原因綜合起來發(fā)給調(diào)用者峦萎。

個(gè)人覺得cancel execution這個(gè)用處不大,很少有需要去取消執(zhí)行的忆首。

而最大的用處應(yīng)該是第二點(diǎn)爱榔。

3、submit方便Exception處理

意思就是如果你在你的task里會拋出checked或者unchecked exception糙及,

而你又希望外面的調(diào)用者能夠感知這些exception并做出及時(shí)的處理详幽,那么就需要用到submit,通過捕獲Future.get拋出的異常浸锨。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末唇聘,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子柱搜,更是在濱河造成了極大的恐慌雳灾,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件冯凹,死亡現(xiàn)場離奇詭異谎亩,居然都是意外死亡炒嘲,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進(jìn)店門匈庭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來夫凸,“玉大人,你說我怎么就攤上這事阱持∝舶瑁” “怎么了?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵衷咽,是天一觀的道長鸽扁。 經(jīng)常有香客問我,道長镶骗,這世上最難降的妖魔是什么桶现? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮鼎姊,結(jié)果婚禮上骡和,老公的妹妹穿的比我還像新娘。我一直安慰自己相寇,他們只是感情好慰于,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著唤衫,像睡著了一般婆赠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上佳励,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天页藻,我揣著相機(jī)與錄音,去河邊找鬼植兰。 笑死份帐,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的楣导。 我是一名探鬼主播废境,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼筒繁!你這毒婦竟也來了噩凹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤毡咏,失蹤者是張志新(化名)和其女友劉穎驮宴,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體呕缭,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡堵泽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年修己,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片迎罗。...
    茶點(diǎn)故事閱讀 38,100評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡睬愤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出纹安,到底是詐尸還是另有隱情尤辱,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布厢岂,位于F島的核電站光督,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏塔粒。R本人自食惡果不足惜结借,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望窗怒。 院中可真熱鬧,春花似錦蓄拣、人聲如沸扬虚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽辜昵。三九已至,卻和暖如春咽斧,著一層夾襖步出監(jiān)牢的瞬間堪置,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工张惹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留舀锨,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓宛逗,卻偏偏與公主長得像坎匿,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子雷激,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評論 2 345

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

  • 進(jìn)程和線程 進(jìn)程 所有運(yùn)行中的任務(wù)通常對應(yīng)一個(gè)進(jìn)程,當(dāng)一個(gè)程序進(jìn)入內(nèi)存運(yùn)行時(shí),即變成一個(gè)進(jìn)程.進(jìn)程是處于運(yùn)行過程中...
    勝浩_ae28閱讀 5,085評論 0 23
  • Java多線程學(xué)習(xí) [-] 一擴(kuò)展javalangThread類 二實(shí)現(xiàn)javalangRunnable接口 三T...
    影馳閱讀 2,952評論 1 18
  • 本文主要講了java中多線程的使用方法替蔬、線程同步、線程數(shù)據(jù)傳遞屎暇、線程狀態(tài)及相應(yīng)的一些線程函數(shù)用法承桥、概述等。 首先講...
    李欣陽閱讀 2,442評論 1 15
  • 單任務(wù) 單任務(wù)的特點(diǎn)是排隊(duì)執(zhí)行根悼,也就是同步凶异,就像再cmd輸入一條命令后蜀撑,必須等待這條命令執(zhí)行完才可以執(zhí)行下一條命令...
    Steven1997閱讀 1,166評論 0 6
  • 按照風(fēng)水先生的說法,取其諧音唠帝,門前栽種金銀花屯掖,肯定能旺家,這是我種金銀花的本意襟衰! 第一年剛栽種贴铜,只開了少量的金銀花...
    隨遇而安20188閱讀 13,924評論 0 1