《Java高并發(fā)編程詳解》基礎(一)

  • 讀《Java高并發(fā)編程詳解》筆記景殷,這本書筆者的收獲很大,配合王文君汪老師的視頻教學基本上可以將線程學的很透徹妖枚,很感謝前輩帶給的這些智慧結(jié)晶运提。以下未我讀本書和看視頻對書的一些摘錄和總結(jié),以及一些補充改含。順序按照書的思路走的情龄。
  • 本篇是最基礎的部分,筆者花了很長時間去學習捍壤,看視頻骤视,敲實例,同時對照著java8的官方文檔鹃觉,再點進去學習源碼专酗,旨意是完全搞懂。筆者認為基礎知識學習多久都是值得的盗扇。

1.線程

  1. 定義:

進程是操作系統(tǒng)動態(tài)執(zhí)行的基本單元祷肯,每一個進程至少要有一個線程運行沉填,線程是執(zhí)行進程的基本單元。

  1. 線程生命周期:


    網(wǎng)圖-線程生命周期

①. 創(chuàng)建狀態(tài)(New):當線程對象創(chuàng)建后佑笋,即進入創(chuàng)建狀態(tài)翼闹。

new關(guān)鍵字僅為創(chuàng)建一個線程類,在沒有調(diào)用start()方法前允青,它就是一個普通的java類橄碾。

②. 就緒狀態(tài)(Runnable):調(diào)用start()方法,線程即進入就緒狀態(tài)颠锉。處于就緒狀態(tài)的線程法牲,隨時等待cpu調(diào)度執(zhí)行。

當執(zhí)行start()方法后琼掠,才會在jvm中創(chuàng)建線程拒垃,此時線程等待cpu調(diào)度運行。除去意外失望瓷蛙,該狀態(tài)只能進入Running狀態(tài)悼瓮。

③. 運行狀態(tài)(Running):當CPU調(diào)度處于就緒狀態(tài)的線程后,線程才得以執(zhí)行艰猬。

此時線程根據(jù)不同的指令可轉(zhuǎn)換轉(zhuǎn)臺為Runable横堡,Blocked和Dead狀態(tài)。①.cup輪詢調(diào)度和yeild()進入Runable.②.sleep()/wait()/join()方法進入Blocked.③.執(zhí)行完畢進入Dead.

④. 阻塞狀態(tài)(Blocked):處于運行狀態(tài)的線程冠桃,由于原因命贴,暫時放棄對cpu的使用權(quán),停止執(zhí)行食听,此時進入阻塞狀態(tài)胸蛛,直到進入就緒狀態(tài)。

此時線程可轉(zhuǎn)換成Dead和Runable狀態(tài)樱报。①.線程意外死亡進入Dead葬项。②.線程被其他線程notify/notifyall方法喚醒,完成休眠迹蛤,interrupt打斷等進入Runnable.

⑤. 死亡狀態(tài)(Dead):線程執(zhí)行結(jié)束民珍,或異常退出,結(jié)束生命周期笤受。

  1. 線程的設計模式

    3.1. Thread中的模板設計模式

    • thread啟動調(diào)用過程

    1.當Thread處于Runable狀態(tài)穷缤,此時調(diào)用start()方法啟動線程。
    2.start()方法調(diào)用本地方法棧(JNI)中方法start)()箩兽。
    3.由JNI的start0()方法調(diào)用Run()方法,執(zhí)行線程邏輯。
    4.線程在運行狀態(tài)和死亡狀態(tài)再次調(diào)用start()方法章喉,會拋IllegalThreadStateException異常

    • 模板設計模式應用

    1.由父類抽象出一個模板汗贫,而子類通過重寫該方法而重寫實現(xiàn)具體邏輯身坐,其中父類控制邏輯調(diào)用。
    2.模板模式主要由抽象模板(Abstract Template)角色和具體模板(Concrete Template)角色組成落包。父類實現(xiàn)模板方法以final修飾部蛇,子類實現(xiàn)模板方法所控制的具體的操作方法
    3.Thread的run和start就是一個模板設計模式的設計。

    3.2. 使用Runable()接口的策略模式

    • Runable接口

    1.由于多個線程所實現(xiàn)的run方法控制具體邏輯咐蝇,每次創(chuàng)建線程的時候都需要隱式創(chuàng)建該方法涯鲁,故此java提供一個接口Runnable來將線程的控制和業(yè)務邏輯分離開。
    2.創(chuàng)建線程只有一種方式有序,即構(gòu)造Thread類抹腿,而實現(xiàn)現(xiàn)成的執(zhí)行單元有兩種方式,第一種是重寫Thread的run方法旭寿,第二種是實現(xiàn)Runnable接口的run方法警绩,并將Runable接口實例用作構(gòu)造Thread的參數(shù)。
    3.策略模式的目的是將線程的控制本身和業(yè)務邏輯的運行分離開盅称,達到職責分明肩祥,功能單一的原則。
    4.Thread類的run方法不能共享缩膝,而實現(xiàn)Runnable的實例則可以構(gòu)造不同的Thread實例混狠。

ps:

  1. 策略模式和模板模式----虛無境
  2. Java 設計模式 ---- 模板設計模式
  3. 策略模式(Strategy)----java程序媛之家

2.Thread構(gòu)造函數(shù)

  1. 線程名

1.在構(gòu)造Thread時,可以手動為該線程命名疾层。
2.若創(chuàng)建線程沒有命名将饺,默認以"Thread-"作為前綴與一個以0開始自增的數(shù)字進行組合,這個自增函數(shù)在整個jvm進程中將不斷自增云芦。
3.若同時創(chuàng)建2個線程俯逾,第一個線程使用指定名,第二個線程使用默認名舅逸,則第二個線程以"Thread-1"命名桌肴,即在jvm中沒有一個線程,命名數(shù)字都將自增琉历,不論是否適用該線程默認名坠七。
4.mian()線程的線程名為"mian"。
5.在線程啟動前旗笔,可以通過方法setName()修改線程名彪置,但是啟動后,名字不再被修改蝇恶。
6.靜態(tài)方法:Thread.currentThread().getName() 獲取線程名

  1. 線程父子關(guān)系

一個線程必然是由另一個線程創(chuàng)建出來的拳魁,而主線程mian是由jvm創(chuàng)建出來的。

  1. 線程與線程組關(guān)系

1.每一個線程創(chuàng)建的時候撮弧,都會分配線程組潘懊,若構(gòu)造線程的時候姚糊,未顯示的指定線程組,則該線程回默認與其父線程同一線程組授舟。
2.mian線程的線程組名為mian救恨。
3.若子線程與父線程同一個線程組,其與父線程的優(yōu)先級一樣释树。

  1. 線程與jvm虛擬機棧

  2. 守護線程

1.設置守護線程:setDaemon()
2.設置守護線程在線程的啟動前才會起作用肠槽。可以使用isDaemon判斷該線程是否為守護線程
3.線程死亡后奢啥,設置setDaemon會拋出異常


3.線程API

  1. sleep方法

1.使用Thread.sleep()會使線程進入Blocked狀態(tài)秸仙,直至休眠完成。
2.jdk1.5以后可以使用更加靈活的枚舉類TimeUnit來替代該方法扫尺。
3.sleep與wait的區(qū)別
?1.sleep是Thread的方法筋栋,休眠是并不釋放資源,不需要定義同步(synchronized)正驻,不需要喚醒弊攘。
?2.wait是Object方法,休眠會釋放資源姑曙,允許其他線程訪問襟交,需要定義同步,需要使用notify()/notifyAll()喚醒伤靠。

  1. yield方法

1.使用yield方法可以式當前線程從Running狀態(tài)進入Runable.方法不常用捣域。
2.CPU在資源不緊張的情況下會自動忽略該方法。
3.當CPU對該線程執(zhí)行了yield方法宴合,該線程將從新位于調(diào)度隊列中焕梅,和其他線程一樣擁有獲得CPU調(diào)度權(quán)的機會。
4.yield與sleep的區(qū)別:
?1.CPU收到sleep指令后卦洽,線程一定會進入Blocked狀態(tài)贞言,此時該線程仍然占據(jù)資源。
?2.CPU接受到y(tǒng)ield命令后阀蒂,根據(jù)資源使用情況可以選擇不執(zhí)行该窗,若執(zhí)行,則線程釋放資源蚤霞,酗失,進入可執(zhí)行隊列,且該線程可以從新競爭CPU使用權(quán)昧绣。

  1. 線程優(yōu)先級

1.線程優(yōu)先級范圍(1 \leq value \leq 10)规肴。
2.mian線程優(yōu)先級為5,線程不設置優(yōu)先級,默認為5奏纪。
3.由于優(yōu)先級設置也是一個提示操作(和yield類似)鉴嗤,所以在CPU空閑時斩启,不起作用序调,而對于非root權(quán)限用戶,也會被忽略兔簇。
4.由于優(yōu)先級的特性发绢,所以在設置事務的先后以及重要性上,不要綁定優(yōu)先級垄琐。
5.thread設置優(yōu)先級:setPriority(num)边酒;線程組設計優(yōu)先級:group.setMaXPriority(num)
6.若某線程組中的線程的優(yōu)先級大于線程組的優(yōu)先級,則該線程的優(yōu)先級最大為該線程組優(yōu)先級狸窘。

  1. interrupt方法

1.調(diào)用interrupt方法會是陷入堵塞(Blocked)狀態(tài)的線程被打斷阻塞墩朦。
2.對于死亡的線程,該方法將被忽略翻擒。
3.每一個線程內(nèi)部都有一個標志氓涣,interrupt flag,來標識當前線程是否被打斷陋气,該標識默認為flag=flase
4.當線程被打斷時劳吠,會拋出InterruptedException異常,可以通過捕獲異常來處理后續(xù)操作巩趁,是否繼續(xù)執(zhí)行該線程和結(jié)束該線程痒玩。
5.使用interrupt方法打斷線程,可以使用isInterrupt()方法(對象方法)议慰,或使用interrupted方法打斷線程(靜態(tài)類方法)方法判斷線程打斷狀況蠢古。
6.使用isInterrupt()方法(對象方法)判斷線程是否被中斷:
?①:若打斷正在執(zhí)行(Running)的線程(未堵塞狀態(tài)),該線程的中斷信號會變?yōu)閠rue别凹,但是該方法并不起作用草讶,線程也不會被打斷Running狀態(tài)。
?②:若打斷正在堵塞狀態(tài)(Blocked)的線程番川,則會拋出InterruptedException異常到涂,線程并不會死亡,是否結(jié)束和處理接下來的邏輯事務看程序的需要颁督,此時中斷信號會變成true,但在拋出異常后恢復為false践啄,程序此時輸出標識為false,避免影響接下來線程方法的調(diào)用沉御。

7.使用interrupted方法打斷線程(靜態(tài)類方法)判斷線程是否被中斷屿讽。情況大致與上述相同,唯一不一樣的是,第二種情況下的伐谈,中斷信號在本次打斷堵塞后一定會變?yōu)閠rue烂完,程序此時第一次輸出標識為true,之后會恢復為false诵棵。僅此區(qū)別而已抠蚣。

  1. join方法

1.只有該線程啟動后,才能調(diào)用join方法履澳。
2.join方法前啟動的線程嘶窄,無法被join方法約束,只有在join后啟動的線程距贷,會在調(diào)用join方法的線程后執(zhí)行柄冲。
3.某線程執(zhí)行join方法,則該線程所在的主線程main線程會等待執(zhí)行忠蝗,知道主線程中所有的有join方法的線程執(zhí)行完畢现横。
PS:join方法詳解

  1. 關(guān)閉線程

1.若線程中有執(zhí)行可中斷方法(阻塞等)操作,可以通過捕獲中斷信號來決定是否退出阁最。
2.由于線程標識可能被擦拭戒祠,或者沒有可中斷方法,使用volatile修飾的開關(guān)flag關(guān)閉線程

4.線程同步

  1. synchronized關(guān)鍵字

①.作用:實現(xiàn)簡單策略防止線程干擾和內(nèi)存一致性錯誤闽撤,若對象對多個線程可見得哆,則對該對象的讀寫將通過線程同步的方式進行。
②.表現(xiàn):某線程獲取與mutex(互斥)關(guān)聯(lián)的monitor(監(jiān)控)鎖哟旗,確保共享變量的互斥訪問贩据,即同一時刻只有一個線程方法同步資源。從而避免數(shù)據(jù)不一致的問題闸餐。
③.synchronized可以對代碼塊或方法進行修飾饱亮,但是不能對class以及變量修飾。

  1. synchronized本質(zhì)

1.每一個對象都與一個monitor相關(guān)聯(lián)舍沙,該monitor的鎖只能被一個線程同一時間獲取近上,其他線程進入阻塞狀態(tài)。
2.對象的monitor鎖都有一個計數(shù)器拂铡,初始為0壹无,表示未被任何線程獲取,若某線程獲取該鎖后感帅,對計數(shù)器加一斗锭,此時該線程為該對象monitor的所有者。此時其他線程會陷入堵塞狀態(tài)失球,知道m(xù)onitor計數(shù)器變?yōu)?岖是,參與從新競爭該鎖。
3.若已經(jīng)擁有該monitor的線程重入,會導致monitor計數(shù)器再次累加豺撑。
4.當monitor計數(shù)器減為0后烈疚,此時該線程釋放鎖的所有權(quán),并和其他線程再次參數(shù)對鎖的競爭聪轿。

  1. This Monitor(對象鎖)

1.即某個類中的對象方法對象方法中的代碼塊被synchronized修飾
2.若同一個類中有多個對象方法或?qū)ο蠓椒ㄖ械拇a塊被synchronized修飾爷肝,若多個線程同時訪問一個該類的實例對象的不同方法,則只有一個線程能夠訪問屹电,因為一個對象實例的對象方法是同一個monitor鎖阶剑。

  1. Class Monitor(類鎖)

1.即某一個類中有多個靜態(tài)方法靜態(tài)方法中的代碼塊被synichronized修飾.由于靜態(tài)方法又稱類方法,所以該鎖稱之為類鎖危号,并不是關(guān)鍵字修飾在類上。
2.若同一個類中有多個靜態(tài)方法或靜態(tài)方法中的代碼塊被synichronized修飾素邪,若多個線程同時訪問該類不同靜態(tài)方法外莲,則只有一個線程能夠訪問,因為該類的靜態(tài)方法使用同一個monitor鎖兔朦。

  1. 死鎖

1.死鎖情況
?①.交叉死鎖偷线,即A線程獲取R1鎖,等待獲取R2鎖沽甥,同時B線程獲取R2鎖声邦,等待獲取R1鎖。
?②.假死死鎖摆舟,CPU占用率升高亥曹,難以檢測。
?②.內(nèi)存不足恨诱,即A媳瞪,B線程執(zhí)行需要占用30內(nèi)存,此時A占據(jù)10照宝,B占據(jù)20蛇受,彼此等待釋放內(nèi)存。

?③.一問一答式數(shù)據(jù)交互厕鹃,客戶端發(fā)送請求兢仰,服務端由于某種原因錯過此時請求,之后客戶端等待回復請求剂碴,服務端也等待請求把将。
?④.數(shù)據(jù)庫鎖,文件鎖汗茄,死循環(huán)引起假死的死鎖
2.死鎖檢測
①.交叉死鎖:一般交叉死鎖會陷入Blocked狀態(tài)秸弛,CPU資源占用不高,很容易借助工具實現(xiàn)。

5.線程通信

6.線程組

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末递览,一起剝皮案震驚了整個濱河市叼屠,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌绞铃,老刑警劉巖镜雨,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異儿捧,居然都是意外死亡荚坞,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門菲盾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來颓影,“玉大人,你說我怎么就攤上這事懒鉴」罟遥” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵临谱,是天一觀的道長璃俗。 經(jīng)常有香客問我,道長悉默,這世上最難降的妖魔是什么城豁? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮抄课,結(jié)果婚禮上唱星,老公的妹妹穿的比我還像新娘。我一直安慰自己剖膳,他們只是感情好魏颓,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吱晒,像睡著了一般甸饱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上仑濒,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天叹话,我揣著相機與錄音,去河邊找鬼墩瞳。 笑死驼壶,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的喉酌。 我是一名探鬼主播热凹,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼泵喘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了般妙?” 一聲冷哼從身側(cè)響起纪铺,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎碟渺,沒想到半個月后鲜锚,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡苫拍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年芜繁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绒极。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡骏令,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出集峦,到底是詐尸還是另有隱情伏社,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布塔淤,位于F島的核電站,受9級特大地震影響速妖,放射性物質(zhì)發(fā)生泄漏高蜂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一罕容、第九天 我趴在偏房一處隱蔽的房頂上張望备恤。 院中可真熱鬧,春花似錦锦秒、人聲如沸露泊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽惭笑。三九已至,卻和暖如春生真,著一層夾襖步出監(jiān)牢的瞬間沉噩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工柱蟀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留川蒙,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓长已,卻偏偏與公主長得像畜眨,于是被迫代替她去往敵國和親昼牛。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

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

  • 單任務 單任務的特點是排隊執(zhí)行康聂,也就是同步贰健,就像再cmd輸入一條命令后,必須等待這條命令執(zhí)行完才可以執(zhí)行下一條命令...
    Steven1997閱讀 1,178評論 0 6
  • 寫在前面的話: 這篇博客是我從這里“轉(zhuǎn)載”的早抠,為什么轉(zhuǎn)載兩個字加“”呢霎烙?因為這絕不是簡單的復制粘貼,我花了五六個小...
    SmartSean閱讀 4,730評論 12 45
  • Java多線程學習 [-] 一擴展javalangThread類 二實現(xiàn)javalangRunnable接口 三T...
    影馳閱讀 2,957評論 1 18
  • 本文主要講了java中多線程的使用方法蕊连、線程同步悬垃、線程數(shù)據(jù)傳遞、線程狀態(tài)及相應的一些線程函數(shù)用法甘苍、概述等尝蠕。 首先講...
    李欣陽閱讀 2,454評論 1 15
  • 進程和線程 進程 所有運行中的任務通常對應一個進程,當一個程序進入內(nèi)存運行時,即變成一個進程.進程是處于運行過程中...
    勝浩_ae28閱讀 5,106評論 0 23