java-樂觀鎖與悲觀鎖

浦濤發表於2018-06-14

我們今天就來了解一下鎖中的樂觀鎖和悲觀鎖。

在面試中,如果是Java後天研發的工程師,很有可能會考到這一個知識點。所以今天也就來說下這個。

兩者的概念

樂觀鎖

  • 根據表面上來看每次去拿資料的時候認為別人都不會修改。所以不會上鎖,有著更寬鬆的鎖機制,減少了效能的開銷。

  • 在更新的時候會根據版本號進行判斷是否有程式去修改這個資料,例如版本號等機制,使用版本號的機制在進行資料提交的時候,如果版本號大於對應的版本號那麼進行更新,否則不進行更新。

  •  在大多數情況下樂觀鎖使用在讀多的應用上。在java中我們所瞭解的atomic包中,常用的執行緒安全的變數是使用的該鎖機制。

  • 樂觀鎖不能解決髒讀問題

悲觀鎖

  • 相對樂觀鎖來說,悲觀鎖具有強烈的獨佔和排他特性。該鎖機制總是假設最壞的情況,每次去拿資料的時候都會認為別人會修改,所以在取資料的時候會進行加鎖的操作。在這樣的情況下,別的程式程式碼操作,需要進行等待操作,直到其拿到鎖為止。

java中實現該兩種機制的鎖

  在整個作業系統中,Cpu是分片操作的,在程式的執行過程中,會進行執行緒間的切換,也就是cpu的切換。Cpu的切換是很耗費時間,所以我們如果想減少CPU的切換,可以讓某個執行緒一直持有該CPU,所以可以採用迴圈的方式來實現。

悲觀鎖

   我們Java中使用的synchronized 就是一種典型的悲觀鎖的實現,該鎖是擁有獨佔性,和排他性保證了執行緒 的安全,所以我們說synchronized是悲觀鎖。

  • 優點:對資料處理安全起到了安全的作用。

  • 缺點:

  1. 因為加鎖 排他性,那麼就會損耗效能,降低了並行性,增加了系統負載。

  2.  容易出現死鎖的情況。 

樂觀鎖

   平常使用的CAS的安全操作類就屬於樂觀鎖機制。還有我們經常說的自旋鎖,輕量級鎖,偏向鎖這些也屬於樂觀鎖。樂觀鎖為什麼樂觀,是因為減少了對CPU之間的切換,掛起,阻塞 ,喚醒等機制的操作造成的開銷。所以在開銷上,樂觀鎖更佔一籌,減少了效能的損耗。建議對效能要求高,讀請求多的使用該機制。

下面介紹下可以使用這些CAS操作一些類的使用

```
       AtomicInteger  one = new AtomicInteger();
       AtomicLong  atomicLong = new AtomicLong();
       AtomicReference student  = new AtomicReference<>();
       one.get() ; //獲得值
       one.addAndGet(2) ;  //增加指定的值
       one.incrementAndGet();  //增加1
       one.getAndSet(0);  //先得到 原先值 然後在置為0
       one.longValue();  //轉為 long型
```

轉載:

原創: mengrui LuckQI


相關文章