天天看點

java-樂觀鎖與悲觀鎖

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

在面試中,如果是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