併發程式設計學習 4 互斥鎖如何保護多個資源

2021-09-12 21:22:09 字數 1821 閱讀 8663

鎖能夠廣泛地被應用,是因為一把鎖能夠保護多個資源,鎖與資源的關係為1:n,當我們需要保護多個資源時,最需要判定的是這些資源間有沒有關聯。

就像電影院的座位和足球場的座位是完全沒有關聯的,因此用電影院門票(鎖)來管理電影院座位,用足球比賽門票(鎖)來管理比賽座位,各自管各自,通過不同的鎖來對資源進行管理。那麼,在下面的**中體現一下這種想法:

public

class

ticket

}// 購買電影票

void

getmovieticket()

}// 檢視足球門票數量

integer getfootballcount()

}// 購買足球門票

void

getfootballticket()

}}

可以看到,對於足球門票和電影票這些不相關的資源,我們用不同的鎖進行管理。用不同的鎖對受保護資源進行精細化的管理,這種鎖就叫做細粒度鎖。為什麼不能用同一把鎖對電影票和足球門票進行統一管理?我相信你也肯定會想到,就是效能問題,如果用細粒度鎖,足球門票和電影票的操作就能並行。

銀行業務中,在轉賬業務中會出現a賬戶轉出100元,b賬戶轉入100元,b賬戶轉出100元,c賬戶轉入100元。a、b、c這三個賬戶是有關聯關係的,那麼,對於這些有關聯關係的資源我們應該怎麼設計鎖?這裡定義乙個account類,這個類有個成員變數餘額:balance,乙個轉賬方法:transfer,以下為**:

public

class

account

}}

那麼如何保證這個操作沒有併發問題?如果直接用synchronized來修飾transfer方法是錯誤的:

synchronized

void

transfer

(account account,

int money)

}

synchronized void transfer的實際意思是synchronized(this) void transfer,this這把鎖只能保護自己的balance而不能保護其他的balance,簡單來說你不能夠用自己的鎖來把別人的財產也保護起來,自己的鎖只能保護自己的財產。那麼該如何操作?下面用以上的a、b、c三個賬號來舉例子。

假設a、b、c三個賬號各有200元,a賬戶轉給b賬戶100元,b賬戶轉給c賬戶100元,最終結果是a有100元、b有200原、c有300元。如果用以上直接用synchronized來修飾transfer方法的話,會出現什麼後果?如果有兩個執行緒同時執行,執行緒1執行a轉b的操作,執行緒2執行b轉c的操作,它們讀到的b餘額都是200元。如果執行緒1執行的比執行緒2快,那麼執行緒1寫入的結果就會被執行緒2的結果覆蓋,最終結果為b的餘額是100元,如果執行緒1比執行緒2慢,結果b的餘額為300元。這實際上就不是互斥了。

為了能夠實現真正的互斥,我們可以使用account.class這個class物件來進行「包場」,所謂的包場就是鎖能覆蓋所有受保護資源。好比電影院,當你包場後,其他人不能進入電影院,更不能使用電影院的資源,只有當你用完才能輪到下乙個人用。回到轉賬這個例子來說,當執行緒1正在執行a轉帳給b時,其他執行緒只能夠等待到執行緒1執行完才能執行轉賬操作,以下是**的實現:

void

transfer

(account account,

int money)

}}

有時候包場並不一定是最好的方法,因為如果當業務量太過龐大,那麼效率就非常低下,上面最佳辦法只能夠應對一些場景,如果想要更好地提高效能,那麼就需要繼續優化。

boost併發程式設計(一) 互斥鎖

這個系列其實是 boost程式庫完全開發指南 的讀書筆記。按照書中的方法 沒跑起來,所以轉到ubuntu下學習了。boost庫在ubuntu下的安裝,直接用apt get install命令安裝就可以了,需要安裝libboost dev libboost system libboost thread...

boost併發程式設計(一) 互斥鎖

這個系列其實是 boost程式庫完全開發指南 的讀書筆記。按照書中的方法 沒跑起來,所以轉到ubuntu下學習了。boost庫在ubuntu下的安裝,直接用apt get install命令安裝就可以了,需要安裝libboost dev libboost system libboost thread...

python之路 併發程式設計之程序 互斥鎖

互斥鎖 將多個任務對修改共享資料的操作由併發變為 序列 沒有互斥鎖的情況下 json檔案 執行檔案 import os import time import json import random from multiprocessing import process def check with o...