NO.33 多線程基礎(chǔ)

多線程:多線程允許我們可以"同時(shí)"執(zhí)行多段代碼。

實(shí)際上多線程是并發(fā)運(yùn)行的荔茬,即:JVM中的線程調(diào)度會為多個(gè)線程分配"CPU時(shí)間片"霸琴,并將這些時(shí)間片盡可能均勻的分配給線程雄家,當(dāng)一個(gè)線程獲取時(shí)間片后氮双,該線程的任務(wù)代碼被CPU執(zhí)行碰酝,其他線程處于等待狀態(tài)。這種宏觀上同時(shí)運(yùn)行而微觀上走走停停的現(xiàn)象稱為并發(fā)戴差。

java中的線程是由Thread的實(shí)例表示送爸。而Thread的創(chuàng)建有兩種方式:

1)繼承Thread并重寫run方法

第一種創(chuàng)建線程的方式雖然定義簡單,但也存在一些不足:

由于java是單繼承的暖释,這經(jīng)常導(dǎo)致在實(shí)際開發(fā)中碱璃,為了復(fù)用一個(gè)類的方法,我們需要繼承那個(gè)類饭入,而自身又希望是一個(gè)線程時(shí)導(dǎo)致的繼承沖突。

繼承了線程需要重寫run方法來定義該線程執(zhí)行的任務(wù)代碼肛真,這就導(dǎo)致了線程與執(zhí)行的任務(wù)有一個(gè)必然的耦合關(guān)系谐丢,不利于線程的重用。

2)實(shí)現(xiàn)Runnable接口并重寫run方法來單獨(dú)定義任務(wù)

下面示例怎么用匿名內(nèi)部類完成線程的兩種方式創(chuàng)建:

匿名內(nèi)部類的兩種方式

線程提供了一個(gè)靜態(tài)方法:static Thread currentThread()

該方法可以獲取運(yùn)行這個(gè)方法的線程

java中所有代碼都是靠線程運(yùn)行的蚓让,main方法也不例外乾忱。只不過運(yùn)行main方法的線程不是由我們創(chuàng)建的。

獲取線程示例

獲取線程信息的相關(guān)方法:

獲取線程標(biāo)識历极、是否存活窄瘟、是否守護(hù)、是否中斷

線程優(yōu)先級:

對于線程調(diào)度的工作趟卸,線程不能干涉蹄葱,即:線程只能被動的等待分配CPU時(shí)間片,而不能主動獲取锄列⊥荚疲可以通過修改線程優(yōu)先級來最大程度改善獲取CPU時(shí)間片的幾率,理論上邻邮,線程優(yōu)先級越高的線程獲取CPU時(shí)間片的次數(shù)越多竣况。

線程的優(yōu)先級有10個(gè)等級,分別用整數(shù)1-10表示筒严。其中1最低丹泉,10最高情萤,5為默認(rèn)值。

理論上完成順序?yàn)椋簃ax摹恨、nor筋岛、min

線程提供了一個(gè)靜態(tài)方法:static void sleep(long ms)

該方法會將運(yùn)行當(dāng)前方法的線程阻塞指定毫秒。

每隔1秒輸出

守護(hù)線程----也稱為后臺線程

默認(rèn)創(chuàng)建出來的線程都是前臺線程睬塌,若要設(shè)置為后臺線程

可以通過線程提供的方法setDaemon來完成泉蝌。

后臺線程使用上與前臺線程一樣,但是在結(jié)束時(shí)機(jī)上有一點(diǎn)是不同的揩晴,即:當(dāng)一個(gè)進(jìn)程結(jié)束時(shí)勋陪,所有正在運(yùn)行的后臺線程都會強(qiáng)制結(jié)束。而進(jìn)程的結(jié)束是當(dāng)一個(gè)進(jìn)程中所有前臺線程都結(jié)束時(shí)結(jié)束硫兰。

所以將來開發(fā)中可以將一直保持運(yùn)行的任務(wù)诅愚,但是可以隨著程序一同結(jié)束的放在后臺線程上運(yùn)行。

下面示例可以想象為泰坦尼克號中rose(一個(gè)前臺進(jìn)程)跳了之后劫映,jack(守護(hù)進(jìn)程)也隨之jump

守護(hù)進(jìn)程設(shè)置案例

線程提供了一個(gè)方法:join

join可以協(xié)調(diào)線程間同步運(yùn)行

網(wǎng)頁上文字與圖片顯示案例----文字先顯示违孝,等待圖片下載完畢然后顯示

final Thread download。泳赋。雌桑。原因:

當(dāng)一個(gè)方法的局部內(nèi)部類中需要引用該方法的其他局部變量時(shí),該變量必須是final的

在這里main方法的局部內(nèi)部類show中想引用main方法的其他局部變量download,那么download就必須是final修飾的祖今。JDK1.8之后由于內(nèi)存問題被重新定義校坑,不在有這個(gè)問題,所以就不再需要做上述設(shè)定千诬。


多線程并發(fā)安全問題:

當(dāng)多個(gè)線程并發(fā)訪問統(tǒng)一資源時(shí)耍目,由于線程切換時(shí)機(jī)不確定,導(dǎo)致代碼未按照設(shè)計(jì)方式的順序執(zhí)行導(dǎo)致的邏輯混亂徐绑。嚴(yán)重時(shí)可能導(dǎo)致系統(tǒng)癱瘓邪驮。

解決多線程并發(fā)安全的手段是將"各干各的"變?yōu)?排隊(duì)執(zhí)行":

當(dāng)一個(gè)方法被synchronized修飾后,那么該方法稱為“同步方法”傲茄,即:多個(gè)線程不能同時(shí)進(jìn)入到方法

內(nèi)部執(zhí)行毅访。

在方法上使用synchronized修飾后,上鎖的對象就是當(dāng)前方法所屬對象盘榨,即:方法中看到的this

多線程訪問將會排隊(duì)執(zhí)行

為避免過多的拖慢系統(tǒng)處理速度俺抽,有效的縮小同步范圍可以在保證并發(fā)安全的前提下提高并發(fā)的效率。

synchronized修飾代碼塊排隊(duì)執(zhí)行

靜態(tài)方法使用synchronized较曼,那么一定具有同步效果

靜態(tài)方法上鎖的對象是該方法所屬類的類對象磷斧。實(shí)際上JVM在加載一個(gè)類的class文件時(shí),會實(shí)例化一個(gè)Class類型的實(shí)例去保存該類的信息(屬性,方法等)弛饭。所以JVM中每個(gè)加載過的類都有且只有一個(gè)Class的實(shí)例用于表示它這個(gè)Class的實(shí)例就是該類的類對象冕末。

多線程通過類名或不同對象調(diào)用dosome()方法都會排隊(duì)執(zhí)行

互斥鎖:

同一個(gè)對象不同線程調(diào)用不同方法依然是排隊(duì)執(zhí)行

將集合或Map轉(zhuǎn)換為線程安全的:

轉(zhuǎn)換為線程安全的,防止多線程操作使混亂

但是要注意:線程安全的集合也不與迭代器遍歷該集合的操作互斥侣颂。但是迭代器要求遍歷的過程中不能通過集合的方法增刪元素档桃,否則會拋出異常,所以在多個(gè)線程間有這樣的操作時(shí)憔晒,需要自行維護(hù)遍歷集合與集合元素操作間的互斥關(guān)系藻肄。


線程池----主要解決兩個(gè)問題:

1)控制線程數(shù)量。因?yàn)榫€程數(shù)多了拒担,會導(dǎo)致內(nèi)存開銷大嘹屯,嚴(yán)重時(shí)會導(dǎo)致系統(tǒng)癱瘓,并且由于線程數(shù)量多會導(dǎo)致CPU過度切換从撼,拖慢系統(tǒng)響應(yīng)州弟。

2)重用線程

線程池執(zhí)行任務(wù)

BlockingQueue是雙緩沖隊(duì)列。

在多線程并發(fā)時(shí)低零,若需要使用隊(duì)列婆翔,我們可以使用Queue,但是要解決一個(gè)問題就是同步掏婶,但同步操作會降低并發(fā)對Queue操作的效率啃奴。

BlockingQueue內(nèi)部使用兩條隊(duì)列,可允許兩個(gè)線程同時(shí)向隊(duì)列一個(gè)做存儲雄妥,一個(gè)做取出操作纺腊。在保證并發(fā)安全的同時(shí)提高了隊(duì)列的存取效率。

創(chuàng)建方式如下:

BlockingQueue queue = new LinkedBlockingQueue();

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末茎芭,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子誓沸,更是在濱河造成了極大的恐慌梅桩,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拜隧,死亡現(xiàn)場離奇詭異宿百,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)洪添,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門垦页,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人干奢,你說我怎么就攤上這事痊焊。” “怎么了?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵薄啥,是天一觀的道長辕羽。 經(jīng)常有香客問我,道長垄惧,這世上最難降的妖魔是什么刁愿? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮到逊,結(jié)果婚禮上铣口,老公的妹妹穿的比我還像新娘。我一直安慰自己觉壶,他們只是感情好脑题,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著掰曾,像睡著了一般旭蠕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上旷坦,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天掏熬,我揣著相機(jī)與錄音,去河邊找鬼秒梅。 笑死旗芬,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的捆蜀。 我是一名探鬼主播疮丛,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼辆它!你這毒婦竟也來了誊薄?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤锰茉,失蹤者是張志新(化名)和其女友劉穎呢蔫,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體飒筑,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡片吊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了协屡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片俏脊。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖肤晓,靈堂內(nèi)的尸體忽然破棺而出爷贫,到底是詐尸還是另有隱情认然,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布沸久,位于F島的核電站季眷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏卷胯。R本人自食惡果不足惜子刮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望窑睁。 院中可真熱鬧挺峡,春花似錦、人聲如沸担钮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽箫津。三九已至狭姨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間苏遥,已是汗流浹背饼拍。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留田炭,地道東北人师抄。 一個(gè)月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像教硫,于是被迫代替她去往敵國和親叨吮。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360

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

  • Java-Review-Note——4.多線程 標(biāo)簽: JavaStudy PS:本來是分開三篇的瞬矩,后來想想還是整...
    coder_pig閱讀 1,655評論 2 17
  • 下面是我自己收集整理的Java線程相關(guān)的面試題茶鉴,可以用它來好好準(zhǔn)備面試。 參考文檔:-《Java核心技術(shù) 卷一》-...
    阿呆變Geek閱讀 14,860評論 14 507
  • 寫在前面的話: 這篇博客是我從這里“轉(zhuǎn)載”的景用,為什么轉(zhuǎn)載兩個(gè)字加“”呢涵叮?因?yàn)檫@絕不是簡單的復(fù)制粘貼,我花了五六個(gè)小...
    SmartSean閱讀 4,743評論 12 45
  • 一位朋友的字
    雪國的夢魘閱讀 264評論 0 2
  • 2016年11月11日丛肢,這個(gè)電商界熱鬧非凡的日子,也是我等單身汪狂刷存在感的日子剿干,淘寶再一次刷新了銷售記錄蜂怎,而我們...
    小南五閱讀 284評論 0 1