欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java concurrency之非公平鎖_動力節(jié)點(diǎn)Java學(xué)院整理

 更新時(shí)間:2017年06月12日 15:34:07   作者:skywang12345  
本篇文章主要介紹了Java concurrency之非公平鎖,詳細(xì)的介紹了獲取和釋放非公平鎖,有興趣的同學(xué)可以了解一下

獲取非公平鎖(基于JDK1.7.0_40)

非公平鎖和公平鎖在獲取鎖的方法上,流程是一樣的;它們的區(qū)別主要表現(xiàn)在“嘗試獲取鎖的機(jī)制不同”。簡單點(diǎn)說,“公平鎖”在每次嘗試獲取鎖時(shí),都是采用公平策略(根據(jù)等待隊(duì)列依次排序等待);而“非公平鎖”在每次嘗試獲取鎖時(shí),都是采用的非公平策略(無視等待隊(duì)列,直接嘗試獲取鎖,如果鎖是空閑的,即可獲取狀態(tài),則獲取鎖)。 

1. lock()

lock()在ReentrantLock.java的NonfairSync類中實(shí)現(xiàn),它的源碼如下:
final void lock() {
  if (compareAndSetState(0, 1))
    setExclusiveOwnerThread(Thread.currentThread());
  else
    acquire(1);
}

說明:

lock()會先通過compareAndSet(0, 1)來判斷“鎖”是不是空閑狀態(tài)。是的話,“當(dāng)前線程”直接獲取“鎖”;否則的話,調(diào)用acquire(1)獲取鎖。

(01) compareAndSetState()是CAS函數(shù),它的作用是比較并設(shè)置當(dāng)前鎖的狀態(tài)。若鎖的狀態(tài)值為0,則設(shè)置鎖的狀態(tài)值為1。

(02) setExclusiveOwnerThread(Thread.currentThread())的作用是,設(shè)置“當(dāng)前線程”為“鎖”的持有者。

“公平鎖”和“非公平鎖”關(guān)于lock()的對比

  1. 公平鎖   -- 公平鎖的lock()函數(shù),會直接調(diào)用acquire(1)。
  2. 非公平鎖 -- 非公平鎖會先判斷當(dāng)前鎖的狀態(tài)是不是空閑,是的話,就不排隊(duì),而是直接獲取鎖。

2. acquire()

acquire()在AQS中實(shí)現(xiàn)的,它的源碼如下:

public final void acquire(int arg) {
  if (!tryAcquire(arg) &&
    acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
    selfInterrupt();
}

(01) “當(dāng)前線程”首先通過tryAcquire()嘗試獲取鎖。獲取成功的話,直接返回;嘗試失敗的話,進(jìn)入到等待隊(duì)列依次排序,然后獲取鎖。

(02) “當(dāng)前線程”嘗試失敗的情況下,會先通過addWaiter(Node.EXCLUSIVE)來將“當(dāng)前線程”加入到"CLH隊(duì)列(非阻塞的FIFO隊(duì)列)"末尾。

(03) 然后,調(diào)用acquireQueued()獲取鎖。在acquireQueued()中,當(dāng)前線程會等待它在“CLH隊(duì)列”中前面的所有線程執(zhí)行并釋放鎖之后,才能獲取鎖并返回。如果“當(dāng)前線程”在休眠等待過程中被中斷過,則調(diào)用selfInterrupt()來自己產(chǎn)生一個(gè)中斷。

“公平鎖”和“非公平鎖”關(guān)于acquire()的對比

公平鎖和非公平鎖,只有tryAcquire()函數(shù)的實(shí)現(xiàn)不同;即它們嘗試獲取鎖的機(jī)制不同。這就是我們所說的“它們獲取鎖策略的不同所在之處”!

非公平鎖的tryAcquire()在ReentrantLock.java的NonfairSync類中實(shí)現(xiàn),源碼如下:

protected final boolean tryAcquire(int acquires) {
  return nonfairTryAcquire(acquires);
}

nonfairTryAcquire()在ReentrantLock.java的Sync類中實(shí)現(xiàn),源碼如下:

final boolean nonfairTryAcquire(int acquires) {
  // 獲取“當(dāng)前線程”
  final Thread current = Thread.currentThread();
  // 獲取“鎖”的狀態(tài)
  int c = getState();
  // c=0意味著“鎖沒有被任何線程鎖擁有”
  if (c == 0) {
    // 若“鎖沒有被任何線程鎖擁有”,則通過CAS函數(shù)設(shè)置“鎖”的狀態(tài)為acquires。
    // 同時(shí),設(shè)置“當(dāng)前線程”為鎖的持有者。
    if (compareAndSetState(0, acquires)) {
      setExclusiveOwnerThread(current);
      return true;
    }
  }
  else if (current == getExclusiveOwnerThread()) {
    // 如果“鎖”的持有者已經(jīng)是“當(dāng)前線程”,
    // 則將更新鎖的狀態(tài)。
    int nextc = c + acquires;
    if (nextc < 0) // overflow
      throw new Error("Maximum lock count exceeded");
    setState(nextc);
    return true;
  }
  return false;
}

說明:

根據(jù)代碼,我們可以分析出,tryAcquire()的作用就是嘗試去獲取鎖。

(01) 如果“鎖”沒有被任何線程擁有,則通過CAS函數(shù)設(shè)置“鎖”的狀態(tài)為acquires,同時(shí),設(shè)置“當(dāng)前線程”為鎖的持有者,然后返回true。

(02) 如果“鎖”的持有者已經(jīng)是當(dāng)前線程,則將更新鎖的狀態(tài)即可。

(03) 如果不術(shù)語上面的兩種情況,則認(rèn)為嘗試失敗。

“公平鎖”和“非公平鎖”關(guān)于tryAcquire()的對比
公平鎖和非公平鎖,它們嘗試獲取鎖的方式不同。

公平鎖在嘗試獲取鎖時(shí),即使“鎖”沒有被任何線程鎖持有,它也會判斷自己是不是CLH等待隊(duì)列的表頭;是的話,才獲取鎖。

而非公平鎖在嘗試獲取鎖時(shí),如果“鎖”沒有被任何線程持有,則不管它在CLH隊(duì)列的何處,它都直接獲取鎖。

釋放非公平鎖(基于JDK1.7.0_40)

非公平鎖和公平鎖在釋放鎖的方法和策略上是一樣的。

總結(jié)

公平鎖和非公平鎖的區(qū)別,是在獲取鎖的機(jī)制上的區(qū)別。表現(xiàn)在,在嘗試獲取鎖時(shí) —— 公平鎖,只有在當(dāng)前線程是CLH等待隊(duì)列的表頭時(shí),才獲取鎖;而非公平鎖,只要當(dāng)前鎖處于空閑狀態(tài),則直接獲取鎖,而不管CLH等待隊(duì)列中的順序。

只有當(dāng)非公平鎖嘗試獲取鎖失敗的時(shí)候,它才會像公平鎖一樣,進(jìn)入CLH等待隊(duì)列排序等待。

相關(guān)文章

  • 淺談JVM核心之JVM運(yùn)行和類加載

    淺談JVM核心之JVM運(yùn)行和類加載

    本篇文章主要介紹了JVM核心之JVM運(yùn)行和類加載,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • Java實(shí)戰(zhàn)之小米交易商城系統(tǒng)的實(shí)現(xiàn)

    Java實(shí)戰(zhàn)之小米交易商城系統(tǒng)的實(shí)現(xiàn)

    這篇文章將利用Java實(shí)現(xiàn)小米交易商城系統(tǒng),文中采用的技術(shù)有:JSP?、Spring、SpringMVC、MyBatis等,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-04-04
  • 淺談JackSon的幾種用法

    淺談JackSon的幾種用法

    這篇文章主要介紹了淺談JackSon的幾種用法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • 面試題:Java 實(shí)現(xiàn)查找旋轉(zhuǎn)數(shù)組的最小數(shù)字

    面試題:Java 實(shí)現(xiàn)查找旋轉(zhuǎn)數(shù)組的最小數(shù)字

    這篇文章主要介紹了Java 實(shí)現(xiàn)查找旋轉(zhuǎn)數(shù)組的最小數(shù)字,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-07-07
  • 關(guān)于Android觸摸事件分發(fā)的原理詳析

    關(guān)于Android觸摸事件分發(fā)的原理詳析

    觸摸事件分發(fā)機(jī)制一直以來都是Android中比較重要的一大塊,自定義view,各種復(fù)雜的自定義手勢交互都與觸摸事件分發(fā)機(jī)制關(guān)系密,下面這篇文章主要給大家介紹了關(guān)于Android觸摸事件分發(fā)原理的相關(guān)資料,需要的朋友可以參考下
    2022-01-01
  • Mybatis?Web中的數(shù)據(jù)庫操作方法舉例詳解

    Mybatis?Web中的數(shù)據(jù)庫操作方法舉例詳解

    Mybatis是一款優(yōu)秀的持久化框架,用于簡化JDBC的開發(fā),下面這篇文章主要給大家介紹了關(guān)于Mybatis?Web中數(shù)據(jù)庫操作方法的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-09-09
  • 在idea中創(chuàng)建SpringBoot項(xiàng)目

    在idea中創(chuàng)建SpringBoot項(xiàng)目

    這篇文章主要介紹了在idea中創(chuàng)建SpringBoot項(xiàng)目,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-07-07
  • java  Lock接口詳解及實(shí)例代碼

    java Lock接口詳解及實(shí)例代碼

    這篇文章主要介紹了java Lock接口詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • 在java中main函數(shù)如何調(diào)用外部非static方法

    在java中main函數(shù)如何調(diào)用外部非static方法

    這篇文章主要介紹了在java中main函數(shù)如何調(diào)用外部非static方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Java8中Optional的使用方法詳解

    Java8中Optional的使用方法詳解

    這篇文章主要介紹了Java8中Optional的使用方法詳解,傳統(tǒng)的寫代碼方式經(jīng)常會遇到NullPointerException,這就需要我們在代碼中經(jīng)常判空,而判空的寫法又會顯得很累贅,這里就可以用到Optional來簡化代碼,需要的朋友可以參考下
    2024-01-01

最新評論