亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java concurrency之公平鎖(二)_動力節(jié)點Java學院整理

 更新時間:2017年06月12日 15:48:08   作者:skywang12345  
這篇文章主要為大家詳細介紹了Java concurrency之公平鎖的第二篇內(nèi)容,具有一定的參考價值,感興趣的小伙伴們可以參考一下

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

1. unlock()

unlock()在ReentrantLock.java中實現(xiàn)的,源碼如下:

public void unlock() {
  sync.release(1);
}

說明:

unlock()是解鎖函數(shù),它是通過AQS的release()函數(shù)來實現(xiàn)的。
在這里,“1”的含義和“獲取鎖的函數(shù)acquire(1)的含義”一樣,它是設置“釋放鎖的狀態(tài)”的參數(shù)。由于“公平鎖”是可重入的,所以對于同一個線程,每釋放鎖一次,鎖的狀態(tài)-1。

關于AQS, ReentrantLock 和 sync的關系如下:

public class ReentrantLock implements Lock, java.io.Serializable {

  private final Sync sync;

  abstract static class Sync extends AbstractQueuedSynchronizer {
    ...
  }

  ...
}

從中,我們發(fā)現(xiàn):sync是ReentrantLock.java中的成員對象,而Sync是AQS的子類。 

2. release()

release()在AQS中實現(xiàn)的,源碼如下:

public final boolean release(int arg) {
  if (tryRelease(arg)) {
    Node h = head;
    if (h != null && h.waitStatus != 0)
      unparkSuccessor(h);
    return true;
  }
  return false;
}

說明:

release()會先調(diào)用tryRelease()來嘗試釋放當前線程鎖持有的鎖。成功的話,則喚醒后繼等待線程,并返回true。否則,直接返回false。 

3. tryRelease()

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

protected final boolean tryRelease(int releases) {
  // c是本次釋放鎖之后的狀態(tài)
  int c = getState() - releases;
  // 如果“當前線程”不是“鎖的持有者”,則拋出異常!
  if (Thread.currentThread() != getExclusiveOwnerThread())
    throw new IllegalMonitorStateException();

  boolean free = false;
  // 如果“鎖”已經(jīng)被當前線程徹底釋放,則設置“鎖”的持有者為null,即鎖是可獲取狀態(tài)。
  if (c == 0) {
    free = true;
    setExclusiveOwnerThread(null);
  }
  // 設置當前線程的鎖的狀態(tài)。
  setState(c);
  return free;
}

說明:

tryRelease()的作用是嘗試釋放鎖。
(01) 如果“當前線程”不是“鎖的持有者”,則拋出異常。
(02) 如果“當前線程”在本次釋放鎖操作之后,對鎖的擁有狀態(tài)是0(即,當前線程徹底釋放該“鎖”),則設置“鎖”的持有者為null,即鎖是可獲取狀態(tài)。同時,更新當前線程的鎖的狀態(tài)為0。
getState(), setState()在前一章已經(jīng)介紹過,這里不再說明。
getExclusiveOwnerThread(), setExclusiveOwnerThread()在AQS的父類AbstractOwnableSynchronizer.java中定義,源碼如下:

public abstract class AbstractOwnableSynchronizer
  implements java.io.Serializable {

  // “鎖”的持有線程
  private transient Thread exclusiveOwnerThread;

  // 設置“鎖的持有線程”為t
  protected final void setExclusiveOwnerThread(Thread t) {
    exclusiveOwnerThread = t;
  }

  // 獲取“鎖的持有線程”
  protected final Thread getExclusiveOwnerThread() {
    return exclusiveOwnerThread;
  }
  
  ...
}

4. unparkSuccessor()

在release()中“當前線程”釋放鎖成功的話,會喚醒當前線程的后繼線程。
根據(jù)CLH隊列的FIFO規(guī)則,“當前線程”(即已經(jīng)獲取鎖的線程)肯定是head;如果CLH隊列非空的話,則喚醒鎖的下一個等待線程。

下面看看unparkSuccessor()的源碼,它在AQS中實現(xiàn)。

private void unparkSuccessor(Node node) {
  // 獲取當前線程的狀態(tài)
  int ws = node.waitStatus;
  // 如果狀態(tài)<0,則設置狀態(tài)=0
  if (ws < 0)
    compareAndSetWaitStatus(node, ws, 0);

  //獲取當前節(jié)點的“有效的后繼節(jié)點”,無效的話,則通過for循環(huán)進行獲取。
  // 這里的有效,是指“后繼節(jié)點對應的線程狀態(tài)<=0”
  Node s = node.next;
  if (s == null || s.waitStatus > 0) {
    s = null;
    for (Node t = tail; t != null && t != node; t = t.prev)
      if (t.waitStatus <= 0)
        s = t;
  }
  // 喚醒“后繼節(jié)點對應的線程”
  if (s != null)
    LockSupport.unpark(s.thread);
}

說明:

unparkSuccessor()的作用是“喚醒當前線程的后繼線程”。后繼線程被喚醒之后,就可以獲取該鎖并恢復運行了。

關于node.waitStatus的說明,請參考“上一章關于Node類的介紹”。

 總結

“釋放鎖”的過程相對“獲取鎖”的過程比較簡單。釋放鎖時,主要進行的操作,是更新當前線程對應的鎖的狀態(tài)。如果當前線程對鎖已經(jīng)徹底釋放,則設置“鎖”的持有線程為null,設置當前線程的狀態(tài)為空,然后喚醒后繼線程。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • Java 中ConcurrentHashMap的實現(xiàn)

    Java 中ConcurrentHashMap的實現(xiàn)

    本文主要介紹Java 中ConcurrentHashMap的實現(xiàn),這里整理了詳細的資料,及簡單實例代碼,有興趣的小伙伴可以參考下
    2016-09-09
  • java實現(xiàn)OpenGL ES紋理映射的方法

    java實現(xiàn)OpenGL ES紋理映射的方法

    這篇文章主要介紹了java實現(xiàn)OpenGL ES紋理映射的方法,以實例形式較為詳細的分析了紋理映射的實現(xiàn)技巧,需要的朋友可以參考下
    2015-06-06
  • java實現(xiàn)科研信息管理系統(tǒng)

    java實現(xiàn)科研信息管理系統(tǒng)

    這篇文章主要為大家詳細介紹了java科研信息管理系統(tǒng),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • springboot中如何判斷某個bean是否存在

    springboot中如何判斷某個bean是否存在

    這篇文章主要介紹了springboot中如何判斷某個bean是否存在,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • OpenFeign實現(xiàn)遠程調(diào)用

    OpenFeign實現(xiàn)遠程調(diào)用

    這篇文章主要為大家詳細介紹了OpenFeign實現(xiàn)遠程調(diào)用,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 一篇文章帶你入門java網(wǎng)絡編程

    一篇文章帶你入門java網(wǎng)絡編程

    網(wǎng)絡編程是指編寫運行在多個設備(計算機)的程序,這些設備都通過網(wǎng)絡連接起來。本文介紹了一些網(wǎng)絡編程基礎的概念,并用Java來實現(xiàn)TCP和UDP的Socket的編程,來讓讀者更好的了解其原理
    2021-08-08
  • 劍指Offer之Java算法習題精講數(shù)組查找與字符串交集

    劍指Offer之Java算法習題精講數(shù)組查找與字符串交集

    跟著思路走,之后從簡單題入手,反復去看,做過之后可能會忘記,之后再做一次,記不住就反復做,反復尋求思路和規(guī)律,慢慢積累就會發(fā)現(xiàn)質(zhì)的變化
    2022-03-03
  • Java實現(xiàn)解析dcm醫(yī)學影像文件并提取文件信息的方法示例

    Java實現(xiàn)解析dcm醫(yī)學影像文件并提取文件信息的方法示例

    這篇文章主要介紹了Java實現(xiàn)解析dcm醫(yī)學影像文件并提取文件信息的方法,結合實例形式分析了java基于第三方庫文件針對dcm醫(yī)學影像文件的解析操作相關實現(xiàn)技巧,需要的朋友可以參考下
    2018-04-04
  • IntelliJ IDEA中新建Java class的解決方案

    IntelliJ IDEA中新建Java class的解決方案

    今天小編就為大家分享一篇關于IntelliJ IDEA中新建Java class的解決方案,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-10-10
  • SpringBoot實現(xiàn)RabbitMQ監(jiān)聽消息的四種方式

    SpringBoot實現(xiàn)RabbitMQ監(jiān)聽消息的四種方式

    本文主要介紹了SpringBoot實現(xiàn)RabbitMQ監(jiān)聽消息的四種方式,包括@RabbitListener,MessageListener接口,MessageListenerAdapter適配器,@RabbitHandler這幾種,感興趣的可以了解一下
    2024-05-05

最新評論