線程

sleep:Thread的靜態(tài)方法(Thread.sleep())陪蜻,不會(huì)讓出鎖,不需要被喚醒矩屁,睡眠期間過后遍膜,重新獲得cpu資源
wait:Object的非靜態(tài)方法(B.wait()),執(zhí)行后讓出鎖,進(jìn)入等待池扛或,需要被喚醒(notify()和notifyAll())
yield:暫時(shí)讓出CPU資源绵咱,如果有其他線程獲取了CPU資源,就等到下一次執(zhí)行熙兔,否則繼續(xù)執(zhí)行
join:A線程執(zhí)行B線程的join()方法悲伶,執(zhí)行后需要等待B執(zhí)行完才執(zhí)行A

線程安全:
單線程執(zhí)行和多線程執(zhí)行得到的結(jié)果是一樣的

1、不可變
對(duì)象本身不可改變住涉,每次改變都需要新創(chuàng)建一個(gè)對(duì)象麸锉,不需要再采取任何的線程安全保障措施
final關(guān)鍵字修飾;構(gòu)造器私有秆吵;
2淮椰、絕對(duì)線程安全
不需要采取額外的線程安全保障措施
對(duì)象中的方法被synchronized修飾的,也并非絕對(duì)線程安全的對(duì)象纳寂。如Vector的get()主穗、remove()和size()方法,如果其中一個(gè)線程恰好刪除了一個(gè)元素毙芜,另一個(gè)線程恰好在獲取這個(gè)元素時(shí)拋出異常忽媒。此時(shí)需要在線程執(zhí)行的方法中額外加入同步鎖,來保證線程安全腋粥。
3晦雨、相對(duì)線程安全
通常意義上所講的線程安全,如上例子中的Vector隘冲,在大部分情況下是線程安全的闹瞧,但是對(duì)于一些特定順序的連續(xù)調(diào)用,需要做額外的線程安全保障措施展辞,所以我們說Vector就屬于相對(duì)線程安全的類型奥邮。
4、線程兼容
通常意義上所講的線程不安全,對(duì)象本身并不是線程安全的洽腺,但是可以通過正確的同步手段來保障對(duì)象在多線程環(huán)境中可以安全地使用脚粟。
5、線程對(duì)立
排斥多線程的情況蘸朋,無論是否采取同步措施核无,都無法在多線程環(huán)境下使用。
例如Thread類的suspend()方法和resume()方法藕坯,如果兩個(gè)線程同時(shí)持有一個(gè)線程對(duì)象团南,一個(gè)嘗試去中斷線程,一個(gè)嘗試去恢復(fù)線程堕担,并發(fā)進(jìn)行已慢,無論是否同步曲聂,將會(huì)存在死鎖風(fēng)險(xiǎn)

線程安全的實(shí)現(xiàn)方法:

1霹购、互斥同步(阻塞同步)
公平鎖:按一定順序依次獲得鎖
可重入鎖:在公平鎖的基礎(chǔ)上,同一把鎖可以被多次鎖定(例如:按序號(hào)獲得鎖朋腋,此時(shí)有另外一個(gè)擁有相同序號(hào)的線程齐疙,可以不用等待直接獲得鎖)
非公平鎖:在鎖被釋放時(shí),任何一個(gè)等待鎖的線程都有機(jī)會(huì)獲得鎖旭咽,如synchronized
2贞奋、非阻塞同步
CAS指令需要有3個(gè)操作數(shù),分別時(shí)內(nèi)存地址V穷绵,舊的預(yù)期值A(chǔ)轿塔,新值B,當(dāng)且僅當(dāng)V符合A時(shí)仲墨,處理器用B更新A勾缭,否則不執(zhí)行更新
邏輯漏洞(ABA問題):假設(shè)V符合A了,但實(shí)際上A有可能經(jīng)歷了A---B---A的過程
解決方法:版本控制目养,互斥同步(更高效)
3俩由、無同步方案
要保證線程安全,并不是一定就要進(jìn)行同步癌蚁,兩者沒有因果關(guān)系幻梯。
線程本地存儲(chǔ):將需要共享數(shù)據(jù)的代碼保證在一個(gè)線程內(nèi)完成,如消費(fèi)隊(duì)列努释,ThreadLocal(通過threadLocalHashCode(Key)碘梢,找回對(duì)應(yīng)的本地線程變量(Value))

鎖優(yōu)化:

1、自旋鎖與自適應(yīng)自旋
互斥同步對(duì)性能最大的影響是阻塞的實(shí)現(xiàn)伐蒂,掛起線程和恢復(fù)線程的操作都需要轉(zhuǎn)入內(nèi)核態(tài)中完成煞躬,這些操作給系統(tǒng)的并發(fā)性能帶來了很大的影響。
大部分情況下饿自,共享數(shù)據(jù)鎖定狀態(tài)只會(huì)持續(xù)很短時(shí)間汰翠,所以我們可以讓線程不進(jìn)入掛起狀態(tài)龄坪,而是進(jìn)入一個(gè)循環(huán),等待鎖釋放
此時(shí)需要考慮到共享數(shù)據(jù)鎖定狀態(tài)會(huì)持續(xù)很長時(shí)間的情況复唤,自旋鎖等待需要有一定的限制健田,否則只會(huì)白白消耗處理器資源,默認(rèn)自旋次數(shù)10次佛纫,可以通過參數(shù)設(shè)置
自適應(yīng)自旋:自旋時(shí)間不再固定妓局,通過上一次在同一個(gè)鎖上的自旋時(shí)間及擁有者的狀態(tài)來決定,假設(shè)上一次成功了呈宇,虛擬機(jī)會(huì)認(rèn)為這次也有可能成功好爬,進(jìn)而它將允許自旋等待持續(xù)相對(duì)更長的時(shí)間,反之將可能直接省略掉自旋過程甥啄,以避免浪費(fèi)處理器資源

2存炮、鎖消除
虛擬機(jī)及時(shí)編譯器在運(yùn)行時(shí),對(duì)一些代碼上要求同步蜈漓,但是被檢測到不可能存在共享數(shù)據(jù)競爭的鎖進(jìn)行消除
疑問:程序員自己不會(huì)判斷是否需要加鎖穆桂?
答:實(shí)際上大部分看起來不需要加鎖的代碼,都進(jìn)行了同步操作(并不是程序員自己加入的)融虽,例如字符串的連接享完,javac編譯器會(huì)做自動(dòng)優(yōu)化,在JDK1.5前使用StringBuffer進(jìn)行連續(xù)的append(之后是StringBuild)有额,此時(shí)虛擬機(jī)觀察到變量的動(dòng)態(tài)作用域被限制在同一個(gè)方法內(nèi)部般又,其他線程無法訪問到,便會(huì)消除掉這里的鎖

3巍佑、鎖粗化
原則上茴迁,應(yīng)該將同步塊的作用范圍限制得盡量小,這樣做是為了使得需要同步的操作數(shù)量盡可能變小句狼,如果存在鎖競爭笋熬,那等待鎖的線程也能盡快拿到鎖
但是如果一系列的操作對(duì)同一個(gè)對(duì)象反復(fù)加鎖和解鎖,甚至加鎖操作出現(xiàn)在循環(huán)體中腻菇,會(huì)導(dǎo)致不必要的性能損耗
如果虛擬機(jī)探測到有這樣一串零碎的操作都對(duì)同一個(gè)對(duì)象加鎖胳螟,將會(huì)把鎖同步的范圍擴(kuò)展(粗化)到整個(gè)操作序列的外部

4、輕量級(jí)鎖
輕量級(jí)鎖的本意是筹吐,在沒有多線程競爭的前提下糖耸,減少傳統(tǒng)的重量級(jí)鎖使用操作系統(tǒng)互斥量產(chǎn)生的性能消耗(進(jìn)程在用戶態(tài)和內(nèi)核態(tài)之間切換的開銷)

對(duì)象頭(Mark Word)一般包括運(yùn)行時(shí)數(shù)據(jù),hash碼丘薛,GC分代年齡嘉竟,鎖標(biāo)志位,數(shù)組長度等信息

當(dāng)代碼進(jìn)入同步塊時(shí),如果同步對(duì)象沒有被鎖定(鎖標(biāo)志位為"01"狀態(tài))舍扰,虛擬機(jī)首先將在當(dāng)前線程的棧幀中建立一個(gè)名為鎖記錄(Lock Record)的空間倦蚪,用于存儲(chǔ)鎖對(duì)象目前的對(duì)象頭的拷貝,然后虛擬機(jī)嘗試將對(duì)象的對(duì)象頭更新為指向鎖記錄的指針边苹,如果成功了陵且,那么這個(gè)線程就擁有了該對(duì)象的鎖,并且對(duì)象頭的鎖標(biāo)志為更新為“00”狀態(tài)个束,即表示此對(duì)象處于輕量級(jí)鎖定狀態(tài)


image.png

如果這個(gè)更新操作失敗了慕购,虛擬機(jī)首先會(huì)檢查對(duì)象頭是否指向當(dāng)前線程的棧幀,如果是則說明當(dāng)前線程已經(jīng)擁有了這個(gè)對(duì)象的鎖茬底,那就可以直接進(jìn)入同步塊繼續(xù)執(zhí)行沪悲,否則說明這個(gè)鎖對(duì)象已經(jīng)被其他線程搶占了。如果有兩條以上的線程爭用同一個(gè)鎖阱表,那輕量級(jí)鎖就不再有效殿如,要膨脹為重量級(jí)鎖,鎖標(biāo)志的狀態(tài)值變?yōu)椤?0”捶枢,對(duì)象頭中存儲(chǔ)的就是指向重量級(jí)鎖的指針

上面描述的是加鎖過程握截,解鎖也是通過CAS操作來進(jìn)行的,如果對(duì)象頭仍指向著線程的鎖記錄烂叔,那就用CAS操作把對(duì)象當(dāng)前的對(duì)象頭和棧幀中的對(duì)象頭替換回來,如果成功固歪,則整個(gè)同步過程就完成了蒜鸡,否則,說明有其他線程嘗試過獲取該鎖牢裳,那就要在釋放鎖的同時(shí)逢防,喚醒被掛起的線程(為什么要喚醒被掛起的線程,此處我的理解是蒲讯,因?yàn)橐呀?jīng)存在多線程競爭忘朝,需要膨脹為重量級(jí)鎖,所以釋放輕量級(jí)鎖判帮,喚醒被掛起的線程加入重量級(jí)鎖的競爭)

輕量級(jí)鎖使用CAS操作避免了使用互斥量的開銷局嘁,但如果存在鎖競爭,除了互斥量的開銷外晦墙,還額外發(fā)生了CAS操作悦昵,因此在有競爭的情況下,輕量級(jí)鎖會(huì)比傳統(tǒng)重量級(jí)鎖更慢

5晌畅、偏向鎖
偏向鎖的目的是消除數(shù)據(jù)在無競爭情況下的同步原語但指,可以提高帶有同步但無競爭的程序性能

如果程序中大多數(shù)的鎖總是被多個(gè)不同的線程訪問,那偏向鎖就是多余的,有時(shí)候禁用偏向鎖優(yōu)化反而可以提升性能

偏向鎖會(huì)偏向于第一個(gè)獲得它的線程棋凳,如果在接下來的執(zhí)行過程中拦坠,該鎖沒有被其他的線程獲取,則持有偏向鎖的線程將永遠(yuǎn)不需要再進(jìn)行同步

首次加鎖過程與輕量級(jí)鎖基本一樣

當(dāng)有另外一個(gè)線程去嘗試獲取這個(gè)鎖時(shí)剩岳,偏向模式就宣告結(jié)束贪婉,根據(jù)鎖對(duì)象目前是否處于被鎖定的狀態(tài),撤銷偏向后恢復(fù)到未鎖定或輕量級(jí)鎖定狀態(tài)卢肃,后續(xù)就如輕量級(jí)鎖那樣執(zhí)行

參考文獻(xiàn):《深入理解JAVA虛擬機(jī)》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末疲迂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子莫湘,更是在濱河造成了極大的恐慌尤蒿,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件幅垮,死亡現(xiàn)場離奇詭異腰池,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)忙芒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門示弓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人呵萨,你說我怎么就攤上這事奏属。” “怎么了潮峦?”我有些...
    開封第一講書人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵囱皿,是天一觀的道長。 經(jīng)常有香客問我忱嘹,道長嘱腥,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任拘悦,我火速辦了婚禮齿兔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘础米。我一直安慰自己分苇,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開白布椭盏。 她就那樣靜靜地躺著组砚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪掏颊。 梳的紋絲不亂的頭發(fā)上糟红,一...
    開封第一講書人閱讀 51,208評(píng)論 1 299
  • 那天艾帐,我揣著相機(jī)與錄音,去河邊找鬼盆偿。 笑死柒爸,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的事扭。 我是一名探鬼主播捎稚,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼求橄!你這毒婦竟也來了今野?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤罐农,失蹤者是張志新(化名)和其女友劉穎条霜,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體涵亏,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宰睡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了气筋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拆内。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖宠默,靈堂內(nèi)的尸體忽然破棺而出麸恍,到底是詐尸還是另有隱情,我是刑警寧澤光稼,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布或南,位于F島的核電站,受9級(jí)特大地震影響艾君,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜肄方,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一冰垄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧权她,春花似錦虹茶、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至步清,卻和暖如春要门,著一層夾襖步出監(jiān)牢的瞬間虏肾,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來泰國打工欢搜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留封豪,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓炒瘟,卻偏偏與公主長得像吹埠,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子疮装,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

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