鎖機制

說說線程安全問題

volatile 實現原理

synchronize 實現原理

  • 同步鎖,被它修飾的代碼塊中最多只能有一個線程訪問,其他線程會被阻塞直到獲取到同步鎖。
  • synchronize 採用的是悲觀鎖機制,即線程獲得的是線程獨佔鎖。獨佔鎖意味着其他線程只能依靠阻塞來等待線程釋放鎖。而在CPU轉換線程阻塞時會引起線程上下文切換,當有很多線程競爭鎖的時候,會引起CPU頻繁的上下文切換導致效率很低。

synchronized 與 lock 的區別

  • lock 是一個接口,synchronized 是一個Java關鍵字
  • synchronized 可以修飾方法和代碼塊,修飾普通方法時鎖爲當前對象,修飾靜態方法時鎖爲當前類,修飾代碼塊時鎖爲指定的對象。
  • lock一般使用 ReentrantLock 類做爲鎖。在加鎖和解鎖處需要通過 lock() 和 unlock() 顯示指出。所以一般會在finally塊中寫unlock()以防死鎖。
  • synchronized 用的是悲觀鎖機制。
  • Lock 用的是樂觀鎖方式。

CAS 樂觀鎖

  • 首先,樂觀鎖就是每次都不加鎖,而是假設沒有衝突而去完成某項操作,如果因爲衝突失敗就重試,直到成功爲止。
  • 樂觀鎖實現的機制就是CAS操作,CAS是英文單詞 Compare And Swap 的縮寫,翻譯過來就是比較並替換。
  • CAS機制當中使用了3個基本操作數,內存地址V,舊的預期值A,要修改的新值B
  • 更新一個變量的時候,只有當變量的預期值A和內存地址V當中的實際值相同時,纔會將內存地址V對應的值修改爲B。

ABA 問題

  • 首先,CAS會導致ABA問題,CAS算法實現一個重要的前提是需要取出內存中某時刻的數據並在當下時刻比較並替換,那麼在這個時間差類會導致數據的變化。
  • 比如線程A從內存位置取出value1,這時候線程B執行,將 value1 -> value2 -> value1,這時A進行CAS操作發現內存仍然是 value1,然後線程A操作成功,但是這個過程中線程B可能操作了其他數據,造成問題。
  • 修改方案:應該由“值”比對,優化爲“版本號”比對。參考:AtomicStampedReference.class

樂觀鎖的業務場景及實現方式

  • 版本號機制,在數據表中加上一個版本號version字段,當線程更新數據值時帶上版本號和數據庫中的version版本號比對,相同的話就允許更新,否則重試更新操作,直到更新成功。
  • CAS算法。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章