色色一区二区三区,一本大道道久久九九AV综合,国产香蕉97碰碰视频va碰碰看,综合亚洲国产2020

    <legend id="mljv4"><u id="mljv4"><blockquote id="mljv4"></blockquote></u></legend>

    <sub id="mljv4"><ol id="mljv4"><abbr id="mljv4"></abbr></ol></sub>
      <mark id="mljv4"></mark>
      教育培訓(xùn) > 請問,多個(gè)線程可以讀一個(gè)變量,只有一個(gè)線程可以對這個(gè)變量進(jìn)行寫,到底要不要加鎖?

      請問,多個(gè)線程可以讀一個(gè)變量,只有一個(gè)線程可以對這個(gè)變量進(jìn)行寫,到底要不要加鎖?

      2020-11-17 01:04閱讀(59)

      請問,多個(gè)線程可以讀一個(gè)變量,只有一個(gè)線程可以對這個(gè)變量進(jìn)行寫,到底要不要加鎖?:要加鎖!我們需要保證的是該變量在多線程環(huán)境下是線程安全的。典型的read

      1

      要加鎖!我們需要保證的是該變量在多線程環(huán)境下是線程安全的。

      典型的read write lock場景,Java中比較經(jīng)典的ReentrantReadWriteLock。

      另外多說一句,當(dāng)你不確定要不要加鎖的時(shí)候,就是你需要加鎖的時(shí)候。

      然后你參考MySQL數(shù)據(jù)庫下Innodb存儲引擎默認(rèn)級別是RR,防止臟讀,即當(dāng)我們update一條數(shù)據(jù)的時(shí)候,是加了行鎖的,其他的讀線程在等待著,所以你需不需要加鎖?

      不加鎖會出現(xiàn)什么問題?

      顯然會出現(xiàn)臟讀的問題!

      這也是面試中常見的一種問題,以該題為突破口,帶你進(jìn)入多線程的世界。

      其實(shí)加鎖也很簡單,Java中對該變量進(jìn)行volatile修飾即可!

      不了解volatile的同學(xué)需要學(xué)習(xí)了,本質(zhì)上是為了保證變量操作時(shí)候的內(nèi)存可見性

      那怎么保證內(nèi)存可見性呢?禁止指令重排序、內(nèi)存屏障。

      重點(diǎn)看下圖hotspot虛擬機(jī)的實(shí)現(xiàn):

      當(dāng)我們對一個(gè)變量i進(jìn)行volatile修飾后,Java在字節(jié)碼層面是對這個(gè)變量進(jìn)行了ACC_COLATILE標(biāo)記。當(dāng)我們的JVM虛擬機(jī)看見ACC_COLATILE這個(gè)字節(jié)碼指令后就會對這個(gè)變量加一個(gè)lock指令(cpu層面的),還是一個(gè)的概念。


      有的人說考慮程序的吞吐量,在保證最終一致性的前提下可以不加鎖,那我的理解就是你不是在搞事情就是在埋坑,埋一個(gè)還不容易被發(fā)現(xiàn)的坑。這種坑測試測不出來,線上出問題了還復(fù)現(xiàn)不出來,所以為了安全還是加鎖吧~

      2

      先說結(jié)論:不必要

      • 如果不需要可見性,什么都不需要加
      • 如果需要保證可見性,則需要加volatile關(guān)鍵字。這里可以加鎖,但是沒必要,對性能有影響

      下面簡單解釋下原因:

      加鎖是因?yàn)椴僮鞑皇窃有缘,以i++這個(gè)操作來解釋,看下面兩張圖。

      i++這個(gè)操作需要

      • 先將i的值從內(nèi)存中讀出來
      • 然后加1
      • 最后寫回去

      看上面第二張圖,能很清楚的理解流程吧?

      加鎖就是保證上面的三步是一個(gè)原子操作。

      回到問題,這里只有一個(gè)線程寫,實(shí)際沒有競爭,所以沒必要加鎖。

      但是,看第一張圖,因?yàn)橛兄鲀?nèi)存和本地內(nèi)存的存在

      • 線程先寫入本地內(nèi)存
      • 然后刷入主內(nèi)存
      • 其它內(nèi)存同步主內(nèi)存到工作內(nèi)存
      • 然后從工作內(nèi)存中讀取

      一個(gè)線程寫入后,不能保證其它線程立即看到,這就是可見性問題。

      加了volatile關(guān)鍵字后,會強(qiáng)制操作后同步工作內(nèi)存和主內(nèi)存,保證其它線程立刻看到。

      3

      Java中該變量用volatile約束,因Java每個(gè)線程都會將用到的變量copy到現(xiàn)成工作棧中,而修改了內(nèi)存中變量的值,還需要將此值由線程工作棧寫入到內(nèi)存對應(yīng)區(qū)域,因?yàn)檫@些數(shù)據(jù)讀寫操作要多個(gè)步驟完成,因此不具有原子性,故需要指定volatile關(guān)鍵字修飾變量,讓線程對此變量的操作都直接操作內(nèi)存,而不是有中間的對于線程棧的拷貝動作。

      4

      如果僅僅是你描述的,那不需要加鎖。

      如果需要每次讀取最新值,注意加volatile。

      如果需要及時(shí)拿到最新值,注意使用線程通知手段。

      5

      看你的需求了,如果你不怕丟數(shù)據(jù),或者讀到過期的數(shù)據(jù),就不用加鎖,如果你對數(shù)據(jù)的要求很嚴(yán)格的話,那還是要加鎖的

      6

      這跟多少個(gè)線程讀有啥關(guān)系,就算是一個(gè)線程讀,也是讀寫并發(fā)呀。至于要不要加鎖,看業(yè)務(wù)是不是需要嚴(yán)格的數(shù)據(jù)一致性或者合法性。

      7

      原則上要加鎖。個(gè)別簡單場景可以不加,比如可以確定讀寫不會沖突,或者單個(gè)簡單控制變量考慮volatile。如果是大項(xiàng)目且性能優(yōu)化指標(biāo)不是納秒級的,建議加上鎖,免得埋坑。

      8

      要看變量類型,如果是原子級的,哪就沒問題,不用鎖

      9

      如果臟數(shù)據(jù)對結(jié)果無影響,當(dāng)然可以不加鎖。反之就加鎖了。

      10

      原則上不用,但是(敲重點(diǎn)):如果這個(gè)項(xiàng)目只是你一人的,并且你永遠(yuǎn)對它內(nèi)部邏輯非常清楚,不會因?yàn)樾薷脑黾舆壿嬋ザ鄠(gè)線程寫這個(gè)變量就不用加鎖,反之這如果是個(gè)團(tuán)隊(duì)項(xiàng)目,并且項(xiàng)目邏輯擴(kuò)展會越來越復(fù)雜,并且團(tuán)隊(duì)間項(xiàng)目交接交叉頻繁,文檔不清,新上手的人不清楚邏輯就會可能對這個(gè)變量擴(kuò)展寫邏輯,這種情況就要用鎖,這是要解決項(xiàng)目維護(hù)和擴(kuò)展問題,現(xiàn)在n多項(xiàng)目都存在多次交接和擴(kuò)展后混亂問題。

      相關(guān)問答推薦

      熱點(diǎn)關(guān)注

      一天中什么時(shí)候運(yùn)動減肥效果好抓 小孩能不能練啞鈴多大的孩子適合 小孩嘴唇起皮怎么辦怎樣才能預(yù)防 孩子的羅圈腿是怎么形成的三大因 孩子早戀怎么辦如何有效疏導(dǎo)孩子 醫(yī)生婆婆稱自己專業(yè)孩子的事必須 兒子成人禮送什么禮物好呢給你孩 有孩子的夫妻千萬不要離婚對于孩 小孩千萬別讓老人帶的說法正確嗎 自卑缺乏安全感的孩子怎么改善 怎么讓孩子開口說話 這幾個(gè)方法 怎么讓孩子吃飯 教你如何讓孩子 怎么管教不聽話的孩子 家長首先 頑皮的孩子怎么管教的 這些方法 叛逆期的孩子怎么管教 引導(dǎo)孩子 孩子性格軟弱怎么辦 懦弱的性格 孩子性格偏激怎么辦 孩子性格偏 孩子性格固執(zhí)怎么辦 家長們不妨 愛惹事的孩子怎么管教 不妨試試 養(yǎng)育優(yōu)秀的孩子具備特征,家長要 高考數(shù)學(xué)難出新天際,可有的孩子 “做胎教”和“不做胎教”的孩子 花費(fèi)十幾萬只考了302分 媽媽覺得 甘肅作弊考生留下來的疑團(tuán),是怎 一舉奪魁!高三學(xué)生離校時(shí),校領(lǐng) 高考釘子戶:26次參加高考,今年 D2809次列車因泥石流脫線!此類 “女兒16歲,學(xué)校宿舍里分娩了” 扭曲邪門的內(nèi)容,頻頻出現(xiàn)在教科 川渝地區(qū)幾所大學(xué)實(shí)力很牛!四川