1 aba 問題
如果乙個變數v初次讀取的時候是a值,並且在準備賦值的時候檢查到它仍然是a值,那我們就能說明它的值沒有被其他執行緒修改過了嗎?很明顯是不能的,因為在這段時間它的值可能被改為其他值,然後又改回a,那cas操作就會誤認為它從來沒有被修改過。這個問題被稱為cas操作的 "aba"問題。
jdk 1.5 以後的atomicstampedreference 類
就提供了此種能力,其中的compareandset 方法
就是首先檢查當前引用是否等於預期引用,並且當前標誌是否等於預期標誌,如果全部相等,則以原子方式將該引用和該標誌的值設定為給定的更新值。
2 迴圈時間長開銷大
自旋cas(也就是不成功就一直迴圈執行直到成功)如果長時間不成功,會給cpu帶來非常大的執行開銷。 如果jvm能支援處理器提供的pause指令那麼效率會有一定的提公升,pause指令有兩個作用,第一它可以延遲流水線執行指令(de-pipeline),使cpu不會消耗過多的執行資源,延遲的時間取決於具體實現的版本,在一些處理器上延遲時間是零。第二它可以避免在退出迴圈的時候因記憶體順序衝突(memory order violation)而引起cpu流水線被清空(cpu pipeline flush),從而提高cpu的執行效率。
3 只能保證乙個共享變數的原子操作
cas 只對單個共享變數有效,當操作涉及跨多個共享變數時 cas 無效。但是從 jdk 1.5開始,提供了atomicreference類
來保證引用物件之間的原子性,你可以把多個變數放在乙個物件裡來進行 cas 操作.所以我們可以使用鎖或者利用atomicreference類
把多個共享變數合併成乙個共享變數來操作。
樂觀鎖以及樂觀鎖的實現
樂觀鎖以及樂觀鎖的實現 一 為什麼需要鎖 併發控制 在多使用者環境中,在同一時間可能會有多個使用者更新相同的記錄,這會產生衝突。這就是著名的併發性問題。典型的衝突有 1.丟失更新 乙個事務的更新覆蓋了其它事務的更新結果,就是所謂的更新丟失。例如 使用者a把值從6改為2,使用者b把值從2改為6,則使用...
樂觀鎖以及樂觀鎖的實現
樂觀鎖介紹 樂觀鎖 optimistic locking 相對悲觀鎖而言,樂觀鎖假設認為資料一般情況下不會造成衝突,所以在資料進行提交更新的時候,才會正式對資料的衝突與否進行檢測,如果發現衝突了,則讓返回使用者錯誤的資訊,讓使用者決定如何去做。那麼我們如何實現樂觀鎖呢,一般來說有以下2種方式 1.使...
悲觀鎖與樂觀鎖以及樂觀鎖的實現
總是假設最壞的情況,每次去拿資料的時候都認為別人會修改,所以每 次在拿資料的時候都會上鎖,這樣別人想拿這個資料就會阻塞直到它拿到鎖。傳 統的關係型資料庫裡邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫 鎖等,都是在做操作之前先上鎖。顧名思義,就是很樂觀,每次去拿資料的時候都認為別人不會修改,所...