多線程原理深度剖析

進(jìn)程與線程

進(jìn)程是程序執(zhí)行的最小單位
線程是cpu調(diào)度的最小單位

多線程硬件模型

讀與返回的過(guò)程比較緩慢啃匿,通過(guò)總線
L1、L2、L3三級(jí)緩存览效,速度依次減,容量依次加
計(jì)算單元要讀取數(shù)據(jù)順序?yàn)長(zhǎng)1虫几、L2锤灿、L3、內(nèi)存

可見(jiàn)性問(wèn)題

內(nèi)存有數(shù)據(jù)count=1辆脸,cpu0但校、cpu1把內(nèi)存中的count緩存到本地,都要做count++每强,此時(shí)都返回給內(nèi)存始腾,兩遍count++最終結(jié)果卻是count=2

方案:

  1. 總線上鎖:變成串行,多線程沒(méi)意義了
  2. 數(shù)據(jù)一致性的緩存鎖

緩存鎖

MESI協(xié)議(修改空执、獨(dú)占浪箭、共享、失效)

  1. cpu0辨绊、cpu1都加載count到自己緩存奶栖,本質(zhì)上都是主存里count的副本,count為S狀態(tài)
  2. cpu0想count++门坷,cpu0將本地的count改成M狀態(tài)宣鄙,cpu0通知所有有這個(gè)count副本的其他線程(如cpu1),使其失效
  3. cpu1接到通知的把本地count改成I狀態(tài)并且把修改結(jié)果返回給cpu0
  4. cpu0收到返回后把count++后的新結(jié)果返回給主存默蚌,把本地count改成E狀態(tài)
  5. cpu1這時(shí)要做count++會(huì)發(fā)現(xiàn)本地count變成I狀態(tài)冻晤,需要到主存中取

M-E狀態(tài)之間,cpu類似阻塞绸吸;寫操作放入storebuffer鼻弧、讀操作放入loadbuffer

那什么樣的數(shù)據(jù)需要緩存设江?緩存中數(shù)據(jù)長(zhǎng)什么樣呢?

局部性原理

時(shí)間局部性:主存中有x攘轩,cpu加載x到緩存叉存,認(rèn)為接下來(lái)的操作都需要用到x
空間局部性:兩個(gè)數(shù)據(jù)(x,y)在主存中空間上挨在一起度帮,cpu需要用到x歼捏,但認(rèn)為接下來(lái)的操作也需要用到y(tǒng)。加載的時(shí)候就把(x笨篷,y)都加載到緩存行(64字節(jié))瞳秽。由于存在MESI協(xié)議,導(dǎo)致x冕屯,y互相鎖寂诱,即偽共享

偽共享
可以在代碼部分解決


第二種其實(shí)在優(yōu)化偽共享安聘,long8個(gè)字節(jié)痰洒,前后加8個(gè)long隔離,避免走M(jìn)ESI協(xié)議浴韭,影響效率

解決

硬件層面丘喻,即cpu處理器上,有memorybarrier
軟件層面念颈,JVM規(guī)范匯總泉粉,有四種內(nèi)存屏障(LoadLoadBarries、storestore榴芳、loadstore嗡靡、storeload)->JMM模型(JVM中的一種規(guī)范,規(guī)范了java虛擬機(jī)和計(jì)算機(jī)內(nèi)存如何協(xié)同共存)

JMM模型

JMM指令


lock作用于主內(nèi)存窟感,標(biāo)記變量只能被一條線程讀取
read讨彼、load不能單獨(dú)使用,read+load將變量加載到高速緩存中來(lái)

JVM層面完成了以上這些指令柿祈,用java線程和內(nèi)存完成讀寫操作哈误,并且加上一些內(nèi)存屏障
volatile、sync躏嚎、final關(guān)鍵字

順序性問(wèn)題

指令重排序

由于有storebuffer存在蜜自,buffer的存在使得一些寫操作在storebuffer中進(jìn)行,而一些寫操作是直接寫到內(nèi)存中卢佣,無(wú)法保證storebuffer重荠、內(nèi)存里指令的順序

解決

voliatle、sync

JAVA內(nèi)存模型(多線程軟件模型)

JMM模型


規(guī)范四種內(nèi)存屏障LoadLoadBarries虚茶、StoreStoreLoadStore戈鲁、StoreLoad
lock尾膊、sync、volatile實(shí)現(xiàn)了內(nèi)存屏障

多線程三大核心性質(zhì)

原子性荞彼、可見(jiàn)性、順序性

Voliate(無(wú)法保證原子性)

本質(zhì):讀前插入讀屏障待笑,寫前插入寫屏障鸣皂,就可以解決可見(jiàn)性還有指令重排問(wèn)題

源碼
OrderAccess:storeload:萬(wàn)能屏障,即把寫緩存數(shù)據(jù)全都刷新到內(nèi)存中
linux86中storeload實(shí)現(xiàn):


is_MP:是否是多cpu(多線程)
主要執(zhí)行l(wèi)ock暮蹂,鎖住了0+0(語(yǔ)法規(guī)定寞缝,沒(méi)什么實(shí)際意義)

為什么無(wú)法保證原子性


j++在底層是3條指令,讀取——>加——>寫入
而volatile是指令和指令之間加上內(nèi)存屏障仰泻,所以無(wú)法保證原子性


new操作包含了4條指令

單例模式


多線程情況下荆陆,同時(shí)判斷INSTANCE==null,就不是單例了

如何修改集侯?
加鎖


但是這個(gè)鎖加的范圍太大了被啼,進(jìn)一步優(yōu)化

但這仍然有線程安全問(wèn)題,同時(shí)會(huì)認(rèn)為INSTANCE==null棠枉,鎖住了但不影響另一個(gè)往下走
再加一層判斷

雙重檢查鎖單例模式浓体。注意仍然具有線程安全問(wèn)題。

INSTANCE關(guān)鍵字需不需要加上voliatle呢辈讶?
需要命浴。因?yàn)樽⒁鈔ew這步其實(shí)是4個(gè)指令,防止指令重排序

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末贱除,一起剝皮案震驚了整個(gè)濱河市生闲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌月幌,老刑警劉巖碍讯,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異飞醉,居然都是意外死亡冲茸,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門缅帘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)轴术,“玉大人,你說(shuō)我怎么就攤上這事钦无《涸裕” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵失暂,是天一觀的道長(zhǎng)彼宠。 經(jīng)常有香客問(wèn)我鳄虱,道長(zhǎng),這世上最難降的妖魔是什么凭峡? 我笑而不...
    開(kāi)封第一講書人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任拙已,我火速辦了婚禮,結(jié)果婚禮上摧冀,老公的妹妹穿的比我還像新娘倍踪。我一直安慰自己,他們只是感情好索昂,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布建车。 她就那樣靜靜地躺著,像睡著了一般椒惨。 火紅的嫁衣襯著肌膚如雪缤至。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 52,475評(píng)論 1 312
  • 那天康谆,我揣著相機(jī)與錄音领斥,去河邊找鬼。 笑死秉宿,一個(gè)胖子當(dāng)著我的面吹牛戒突,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播描睦,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼膊存,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了忱叭?” 一聲冷哼從身側(cè)響起隔崎,我...
    開(kāi)封第一講書人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎韵丑,沒(méi)想到半個(gè)月后爵卒,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡撵彻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年钓株,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片陌僵。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡轴合,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出碗短,到底是詐尸還是另有隱情受葛,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站总滩,受9級(jí)特大地震影響纲堵,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜闰渔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一席函、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧冈涧,春花似錦向挖、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)跟畅。三九已至咽筋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間徊件,已是汗流浹背奸攻。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留虱痕,地道東北人睹耐。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像部翘,于是被迫代替她去往敵國(guó)和親硝训。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

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