樂觀鎖:樂觀鎖表示當執行緒對資料進行操作時,認為不會有其他執行緒來修改資料,所以先不上鎖,對資料操作之後,檢查此時的資料是否和最開始執行緒進入時的資料一致,如果一致,那麼就可以認為沒有其他執行緒對資料進行修改,現在可以對資料進行更新;如果不一致,那麼就再讀資料,再操作再檢查資料,直到可以更新資料為止。
悲觀鎖:表示當前執行緒對資料操作時,認為一定會有其他執行緒去更改資料,所以在獲取資源時,就直接上鎖,讓其他執行緒去阻塞。只有當自己操作完成,更新完資料時,才釋放鎖的資源,讓其他執行緒去操作。
樂觀鎖實現的方式:compareandswap , version
compareandswap:cas的三個變數分別是(目標位址,期望值,更改值)
當目標位址的值是期望值時,那麼就把更改只更新到目標位址。
version:當每乙個執行緒對資源進行操作前獲取一次版本號,操作後對比當前資源的版本號,是否與操作前的版本號一致,如果一致,則更新,並且賦予新的版本號;如果不一致,就重新執行此執行緒。
一般使用atomic 包下的類進行操作,volatile保證有序性和可見性,而cas的實現類,保證了原子性。由兩個部分來實現併發的三大特性。
悲觀鎖的實現方式:synchronized
對**塊以及**段,方法,進行修飾,被synchronized修飾過的資源會被加鎖,當執行緒獲取資源時就需要獲取鎖資源,釋放資源時,也要釋放鎖的資源。synchronized同時保證了原子性,有序性,一致性。
樂觀鎖的優點:由於不會對資源上鎖,省去了獲取鎖和釋放鎖的過程,所以在獲取和修改時非常的快速,增加了cpu的吞吐量。使得執行緒的執行更加快速。
樂觀鎖的缺點:(1)aba問題,當前執行緒準備運算元據時,當前的資料是a準備更新資料時檢查的當前資料是a,那就證明當前資源沒有被更新過麼,不能!因為有可能在更新前有兩個執行緒進行了更新,第乙個執行緒把a更新為b,第二個執行緒把b又更新為a。所以當前不能保證沒有其他執行緒操作過。
(2)自旋cas,如果cas執行失敗,那就一直執行,直到成功為止, ,如果當前的執行緒的執行時間很長,那麼這將大大增加cpu的負擔。
悲觀鎖優點:(1)由於每一次執行緒訪問資源時都加上了鎖,所以不必擔心其他執行緒對資料的更新。這對於多執行緒衝突的環境下,cpu利用率非常高。
悲觀鎖的缺點:(1)因為每一次訪問資源都進行了上鎖,所以當普通讀的執行緒要進行訪問資源時,也會阻塞,這就導致資源的利用率不高。
(2)每一次都要獲取鎖和釋放鎖之後,另外的執行緒才可以進行操作, 再獲取鎖和釋放鎖。這就會導致執行緒的切換速度比較慢。
樂觀鎖的適用環境:衝突不嚴重,或者讀操作遠遠大於寫運算元量時,就可以使用樂觀鎖來完成執行緒安全
悲觀鎖的使用環境:衝突很嚴重,寫操作遠遠大於讀運算元量時,就要用悲觀鎖。
不同角度去考慮:
悲觀鎖的使用場景更廣泛,樂觀鎖的使用場景受到了更多的限制,因為cas只能保證單個變數操作的原子性,當涉及到多個變數時,cas也是無能為力的,而悲觀鎖synchronized則可以通過對整個**塊加鎖來處理。而版本號機制,如果查詢和更新資料分別在不同的資料表,也很難通過簡單的版本號去實現;
考慮競爭激烈程度,當競爭不激烈時,樂觀鎖更有優勢,因為悲觀鎖會鎖住**塊或資料,其他執行緒無法同時訪問,影響併發,而加鎖和解鎖也需要消耗一定的資源;當競爭激烈時,悲觀鎖會更有優勢,因為樂觀鎖在執行更新時頻繁失敗,需要不斷重試,浪費cpu資源。
悲觀鎖與樂觀鎖
悲觀鎖與樂觀鎖 悲觀鎖 pessimistic locking 顧名思義就是採用一種悲觀的態度來對待事務併發問題,我們認為系統中的併發更新會非常頻繁,並且事務失敗 了以後重來的開銷很大,這樣以來,我們就需要採用真正意義上的鎖來進行實現。悲觀鎖的基本思想就是每次一 個事務讀取某一條記錄後,就會把這條記...
樂觀鎖與悲觀鎖
悲觀鎖 pessimistic locking 顧名思義就是採用一種悲觀的態度來對待事務併發問題,我們認為系統中的併發更新會非常頻繁,並且事務失敗了以後重來的開銷很大,這樣以來,我們就需要採用真正意義上的鎖來進行實現。悲觀鎖的基本思想就是每次乙個事務讀取某一條記錄後,就會把這條記錄鎖住,這樣 其它的...
樂觀鎖與悲觀鎖
鎖 locking 這個概念在我們學習多執行緒的時候曾經接觸過,其實這裡的鎖和多執行緒裡面處理併發的鎖是乙個道理,都是暴力的把資源歸為自己所有。這裡我們用到鎖的目的就是通過一些機制來保證一些資料在某個操作過程中不會被外界修改,這樣的機制,在這裡,也就是所謂的 鎖 即給我們選定的目標資料上鎖,使其無法...