您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關(guān)三分鐘帶你了解Java中的悲觀鎖和樂觀鎖,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。
樂觀鎖對應(yīng)于生活中樂觀的人總是想著事情往好的方向發(fā)展,悲觀鎖對應(yīng)于生活中悲觀的人總是想著事情往壞的方向發(fā)展。這兩種人各有優(yōu)缺點,不能不以場景而定說一種人好于另外一種人。
悲觀鎖
總是假設(shè)最壞的情況,每次去拿數(shù)據(jù)的時候都認為別人會修改,所以每次在拿數(shù)據(jù)的時候都會上鎖,這樣別人想拿這個數(shù)據(jù)就會阻塞直到它拿到鎖(共享資源每次只給一個線程使用,其它線程阻塞,用完后再把資源轉(zhuǎn)讓給其它線程)。傳統(tǒng)的關(guān)系型數(shù)據(jù)庫里邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。Java中synchronized和ReentrantLock等獨占鎖就是悲觀鎖思想的實現(xiàn)。
樂觀鎖
總是假設(shè)最好的情況,每次去拿數(shù)據(jù)的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數(shù)據(jù),可以使用版本號機制和CAS算法實現(xiàn)。樂觀鎖適用于多讀的應(yīng)用類型,這樣可以提高吞吐量,像數(shù)據(jù)庫提供的類似于write_condition機制,其實都是提供的樂觀鎖。在Java中java.util.concurrent.atomic包下面的原子變量類就是使用了樂觀鎖的一種實現(xiàn)方式CAS實現(xiàn)的。
兩種鎖的使用場景
從上面對兩種鎖的介紹,我們知道兩種鎖各有優(yōu)缺點,不可認為一種好于另一種,像樂觀鎖適用于寫比較少的情況下(多讀場景),即沖突真的很少發(fā)生的時候,這樣可以省去了鎖的開銷,加大了系統(tǒng)的整個吞吐量。但如果是多寫的情況,一般會經(jīng)常產(chǎn)生沖突,這就會導(dǎo)致上層應(yīng)用會不斷的進行retry,這樣反倒是降低了性能,所以一般多寫的場景下用悲觀鎖就比較合適。
樂觀鎖常見的兩種實現(xiàn)方式 樂觀鎖一般會使用版本號機制或CAS算法實現(xiàn)。
版本號機制
一般是在數(shù)據(jù)表中加上一個數(shù)據(jù)版本號version字段,表示數(shù)據(jù)被修改的次數(shù),當數(shù)據(jù)被修改時,version值會加一。當線程A要更新數(shù)據(jù)值時,在讀取數(shù)據(jù)的同時也會讀取version值,在提交更新時,若剛才讀取到的version值為當前數(shù)據(jù)庫中的version值相等時才更新,否則重試更新操作,直到更新成功。
舉一個簡單的例子: 假設(shè)數(shù)據(jù)庫中帳戶信息表中有一個 version 字段,當前值為 1 ;而當前帳戶余額字段( balance )為 $100 。
即compare and swap(比較與交換),是一種有名的無鎖算法。無鎖編程,即不使用鎖的情況下實現(xiàn)多線程之間的變量同步,也就是在沒有線程被阻塞的情況下實現(xiàn)變量的同步,所以也叫非阻塞同步(Non-blocking Synchronization)。CAS算法涉及到三個操作數(shù)
需要讀寫的內(nèi)存值 V 進行比較的值 A 擬寫入的新值 B 當且僅當 V 的值等于 A時,CAS通過原子方式用新值B來更新V的值,否則不會執(zhí)行任何操作(比較和替換是一個原子操作)。一般情況下是一個自旋操作,即不斷的重試。
關(guān)于三分鐘帶你了解Java中的悲觀鎖和樂觀鎖就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。