3.CAS操作(轻量级锁)
1.什么是CAS操作?
2.CAS操作用來干什么?
3.java中的CAS操作是怎么實現的?
4.CAS操作有什么優點?有什么缺點?會帶來什么問題?怎么解決?
1.Q:什么是CAS操作?
A:
CAS是compare and swap,基本過程是:
存在三個值,一個是變量在內存中的值V,一個是該線程期望該變量的值A,另一個是該線程要把該變量修改為的值B。
當線程期望的值等于變量在內存的值時,把該變量修改為值B。
2.Q:CAS操作用來干什么?
A:
CAS可以保證變量的線程安全。(是對變量的操作為原子操作)
CAS可以保證變量的操作是原子操作。從而在只需要保證變量線程安全時,替代synchronized來避免加鎖解鎖的性能消耗,提高性能。
在jdk1.6后的synchronized鎖升級的過程中,輕量級鎖使用的就是CAS操作,輕量級鎖處理的是有少量線程競爭的情況,CAS操作配上和它關系緊密的自旋操作,這樣做的好處也是避免加鎖解鎖,減少性能消耗。
3.Q:java中的CAS操作是怎么實現的?
A:
用unsafe類調用的native方法實現的,native方法是可以直接訪問操作系統底層的c/c++方法。
4.Q:CAS操作有什么優點?有什么缺點?會帶來什么問題?怎么解決?
A:
優點:在只需要保證變量的線程安全時,可以替代synchronized來避免加鎖解鎖,降低性能消耗。
缺點:1.當線程競爭大的時候,線程等不到內存中的值和自己期望的值相等,就一直自旋。此時cpu資源負載很大。
2.會造成ABA問題。
什么是ABA問題?為什么會造成ABA問題?該怎么解決?
ABA過程:
有三個線程:
線程1.期望的值為A,要修改為B
線程2.期望的值為A,要修改為B (被阻塞)
線程3.還沒讀取值,要修改為A
因為一個請求產生了兩個線程,就出了問題。
此刻內存中的值為A,線程1把它修改為B。線程2暫時阻塞,當線程3讀取的時候為B,然后把它修改為A。最后線程2看到現在為A,則又把它修改為了B。
這個過程看起來好像沒有問題,但是當只有一個請求,卻產生兩個線程(線程1,線程2)時就會出現問題。
舉一個銀行轉賬的例子:
用戶余額為100,當他轉走50時,應該剩下50。然后他又充了50,最后結果應該是100才對。
但是當轉錢操作有同時兩個線程做的時候,線程1先把余額從100修改為了50,線程2暫時阻塞。然后充錢操作,線程3把余額從50修改為了100。但是當線程3看到此時為100,最后則錯誤地把余額修改為了50。這樣就造成了問題。
解決方法是:給線程修改變量(進行CAS,compare and set)時加上版本號。
比如轉錢操作對應版本號01線程才能修改,線程1不僅變量值對上了,版本號也對上了為01。所以就修改。
到線程2恢復運作時,此時中間已經有多個操作發生,版本號已經變化,因為版本號不一致,所以線程2修改失敗。
AtomicStampedReference原子類就實現了CAS操作的版本號驗證,可以有效解決ABA問題。
加上相應的版本號是解決ABA問題的有效方法。
總結
以上是生活随笔為你收集整理的3.CAS操作(轻量级锁)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 以太网/FX3U/PLC/工控板/PLC
- 下一篇: 如何设置手机在线客服用户户对话左上角的头