java CAS 樂觀鎖悲觀鎖
前言
悲觀鎖:
一個資源同時被多給請求,多個查詢,多個線程,訪問獲取或需要對它修改時,一次只能一個,其他的阻塞在哪裏一個個來。
代碼中體現:
java中的類鎖
mysql的查詢加for update;
樂觀鎖:
一個資源同時被多給請求,多個查詢,多個線程,訪問獲取或需要對它修改時,默認沒有併發只有當前請求在進行操作。
暴漏的問題:
如果真的是多個請求在修改,可能會造成大家處理的不一致
java中解決方案: CAS
CAS
CAS 其實就是樂觀鎖的核心體現,主要是 1. 先查詢獲取當前值 2.修改時判斷當前值是否和查詢值一致,如果一致就是隻有當前線程處理,沒有就是多線程情況處理失敗,輪詢重試。
題外話:
內存存放數據是正常的做法,java裏面從內存讀寫數據,但是頻繁的讀寫不是辦法,CPU利用率太高,容易IO異常。
怎麼解決?
沒有什麼不是中間層不能解決的,那就做緩存把,線程每次從內存中把需要的數據變量拷取成副本,再結束的時候向內存中寫入。
業務中使用:
(1)AQS,Lock,以及java裏面的各個併發組件也都是這個方案 (手寫組件的時候會用到)
(2)Mysql 中防止一條記錄多線程被改亂,同時業務層面可以接受失敗樂觀鎖機制version
補充
CAS 只是一個方案,不同地方具體體現不一樣,java中可參考AQS具體實現 :
voliate +CAS +CLH輪詢重試 解決多線程併發問題(請參考優質博客閱讀源碼仔細體會,這玩意只看博客永遠搞不明白)