java - 讀寫鎖中 寫鎖的降級問題
問題描述
寫鎖降級的時(shí)候 要求當(dāng)前已經(jīng)獲取到寫鎖的線程把持住寫鎖,然后獲取讀鎖,隨后釋放寫鎖。
那么為什么要求把持住寫鎖呢??
上圖中提到 “ 那么當(dāng)前線程無法感知線程T的數(shù)據(jù)更新 ” 這個(gè)如何理解。如果線程T獲取到了寫鎖,然后對數(shù)據(jù)進(jìn)行了更新,在沒有釋放寫鎖之前,當(dāng)前線程無法感知到數(shù)據(jù)的更新,這個(gè)是沒問題的吧,但是一旦線程T釋放 寫鎖,那么當(dāng)前線程就可以感知到數(shù)據(jù)的更新了,這里理解應(yīng)該沒問題吧?
help me to explain,thx
問題解答
回答1:這是在解釋鎖降級吧,首先寫鎖是獨(dú)占的,讀鎖是共享的,然后讀寫鎖是線程間互斥的,鎖降級的前提是所有線程都希望對數(shù)據(jù)變化敏感,但是因?yàn)閷戞i只有一個(gè),所以會(huì)發(fā)生降級。如果先釋放寫鎖,再獲取讀鎖,可能在獲取之前,會(huì)有其他線程獲取到寫鎖,阻塞讀鎖的獲取,就無法感知數(shù)據(jù)變化了。所以需要先hold住寫鎖,保證數(shù)據(jù)無變化,獲取讀鎖,然后再釋放寫鎖。
回答2:寫鎖不允許其他進(jìn)程的讀寫操作,讀鎖的允許讀操作。就按你抓圖的例子來看,當(dāng)你釋放寫鎖后,T進(jìn)程獲取了寫鎖,這時(shí)你就無法獲取讀鎖了,所以要先獲取讀鎖后,再釋放寫鎖。
首先你沒理解讀寫鎖的意義,讀鎖的存在意味著不允許其他寫操作的存在。按照你提供的例子,可能存在一個(gè)事務(wù)線程不希望自己的操作被別的線程中斷,而這個(gè)事務(wù)操作可能分成多部分操作更新不同的數(shù)據(jù)(或表)甚至非常耗時(shí)。如果長時(shí)間用寫鎖獨(dú)占,顯然對于某些高響應(yīng)的應(yīng)用是不允許的,所以在完成部分寫操作后,退而使用讀鎖降級,來允許響應(yīng)其他進(jìn)程的讀操作。只有當(dāng)全部事務(wù)完成后才真正釋放鎖。按你的理解如果當(dāng)中寫鎖被其他線程占用,那么這個(gè)事務(wù)線程將不得不中斷等待別的寫鎖釋放。
回答3:“ 那么當(dāng)前線程無法感知線程T的數(shù)據(jù)更新 ”
T1 讀取 數(shù)據(jù) Data時(shí),將數(shù)據(jù)值復(fù)制到當(dāng)前線程的上下文,因此其他線程沒有辦法感知數(shù)據(jù)是否更新。只要當(dāng)數(shù)據(jù)提交內(nèi)存中,即Heap中,其他線程才可以得到最新值。
相關(guān)文章:
1. css - 新手做響應(yīng)式布局, 斷點(diǎn)過后右側(cè)出現(xiàn)空白,求幫助,謝謝。2. javascript - 關(guān)于<a>元素與<input>元素的JS事件運(yùn)行問題3. javascript - ES6 中能否把 class 屬性 方法 分文件?4. python - 能通過CAN控制一部普通的家用轎車嗎?5. mysql - 查詢字段做了索引為什么不起效,還有查詢一個(gè)月的時(shí)候數(shù)據(jù)都是全部出來的,如果分拆3次的話就沒問題,為什么呢。6. mysql - 記得以前在哪里看過一個(gè)估算時(shí)間的網(wǎng)站7. ID主鍵不是自增的嗎 為什么還要加null8. 大家好,我想請問一下怎么做搜索欄能夠搜索到自己網(wǎng)站的內(nèi)容。9. MySQL中的enum類型有什么優(yōu)點(diǎn)?10. css - 關(guān)于border-image
