一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java 基于AQS實現自定義同步器的示例

Java 基于AQS實現自定義同步器的示例

2021-08-17 10:20心悅君兮君不知-睿 Java教程

這篇文章主要介紹了Java 基于AQS實現自定義同步器的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下

一、AQS-條件變量的支持

在如下代碼中,當另外一個線程調用條件變量的signal方法的時候(必須先調用鎖的lock方法獲取鎖),在內部會把條件隊列里面隊頭的一個線程節點從條件隊列里面移除并且放入AQS的阻塞隊列里面,然后激活這個線程。

  1. public final void signal() {
  2.  if(!isHeldExclusively()) {
  3.   throw IllegalMonitorException();
  4.  }
  5.  Node first = firstWaiter;
  6.  if(first != null){
  7.   // 將條件隊列頭元素移動到AQS隊列
  8.   doSignal(first);
  9.  }
  10. }
  • 需要注意的是,AQS提供了ConditionObject的實現,并沒有提供newCondition函數,該函數用來new一個ConditionObject對象,需要由AQS的子類來提供newConditon函數
  • 下面來看當一個線程調用條件變量的await()方法而被阻塞后,如何將其放入條件隊列
  1. private Node addConditionWaiter() {
  2.  Node t = lastWaiter;
  3.  ...
  4.  // (1)
  5.  Node node = new Node(Thread.currentThread(),Node.CONDITION);
  6.  // (2)
  7.  if(== null){
  8.   firstWaiter = node;
  9.  }else {
  10.   t.nextWaiter = node; // (3)
  11.  }
  12.  lastWaiter = node; // (4)
  13.  return node;
  14. }
  • 代碼(1)首先根據根據當前線程創建了一個類型為Node.CONDITION的節點,然后通過代碼(2),(3),(4)在單向隊列尾部插入一個元素
  • 注意:當多個線程同時調用lock.lock()方法獲取鎖時,只有一個線程獲取到了鎖,其他線程會被轉換為Node節點插入到lock鎖對應的AQS阻塞里面,并且做自旋CAS嘗試獲取鎖
  • 如果獲取到了鎖的線程又調用對應條件變量的await()方法,則該線程會釋放獲取到的鎖,并被轉化為Node節點插入到條件變量對應的條件隊列里面
  • 這時候因為調用lock.lock()方法被阻塞到AQS隊列里面的一個線程會獲取到被釋放的鎖,如果該線程也調用了條件變量的await()方法則該線程也會被放入條件變量的條件隊列里面
  • 當另外一個線程調用條件變量的signal()或者signalAll()方法的時候,會把條件隊列里面的一個或者全部Node節點移動到AQS的阻塞隊列里面,等待時機獲取鎖。
  • 最后使用一個圖總結:一個鎖對應一個AQS阻塞隊列,對應多個條件變量,每個條件變量有自己的一個條件隊列。

Java 基于AQS實現自定義同步器的示例

二、基于AQS實現自定義同步器

  • 基于AQS實現一個不可重入的鎖,自定義AQS需要重寫一系列的函數,還需要定義原子變量state的含義,在這里我們定義state為0表示目前鎖沒有被線程持有,state為1表示所已經被某一個線程持有,由于是不可重入鎖,所以不需要記錄持有鎖的線程獲取鎖的次數,另外,我們自定義的鎖支持條件變量。
  • 下面來看一下代碼實現
  1. package com.ruigege.LockSourceAnalysis6;
  2.  
  3. import java.util.concurrent.TimeUnit;
  4. import java.util.concurrent.locks.Condition;
  5. import java.util.concurrent.locks.Lock;
  6.  
  7. public class NonReentrantLockME implements Lock,java.io.Serializable{
  8.  // 內部幫助類
  9.  private static class Sync extends AbstractQueueSynchronizer {
  10.   // 是否鎖已經被持有
  11.   protected boolean isHeldExclusively() {
  12.    return getState() == 1;
  13.   }
  14.   
  15.   // 如果state為0,則嘗試獲取鎖
  16.   public boolean tryAcquire(int acquires) {
  17.    assert acquires == 1;
  18.    if(compareAndSetState(0,1)) {
  19.     setExclusiveOwnerThread(Thread.currentThread());
  20.     return true;
  21.    }
  22.    return false;
  23.   }
  24.   
  25.   // 嘗試釋放鎖,設置state為0
  26.   protected boolean tryRelease(int release) {
  27.    assert releases == 1;
  28.    if(getState() == 0) {
  29.     throw new IllegalMonitorStateException();
  30.    }
  31.    setExclusiveOwnerThread(null);
  32.    setState(0);
  33.    return true;
  34.   }
  35.   
  36.   // 提供條件變量接口
  37.   Condition newConditon() {
  38.    return new ConditionObject();
  39.   }
  40.  }
  41.  
  42.  // 創建一個Sync來做具體的工作
  43.  private final Sync sync = new Sync();
  44.  
  45.  public void lock() {
  46.   sync.acquire(1);
  47.  }
  48.  
  49.  public boolean tryLock() {
  50.   return sync.tryAcquire(1);
  51.  }
  52.  
  53.  public void unlock() {
  54.   sync.release(1);
  55.   
  56.  }
  57.  public Condition newCondition() {
  58.   return sync.newConditon();
  59.  }
  60.  
  61.  public boolean isLocked() {
  62.   return sync.isHeldExclusively();
  63.  }
  64.  
  65.  public void lockInterruptibly() throws InterruptedException {
  66.   sync.acquireInterruptibly(1);
  67.  }
  68.  
  69.  public boolean tryLock(long timeout,TimeUnit unit) throws InterruptedException {
  70.   return sync.tryAcquireNanos(1,unit.toNanos(timeout));
  71.  }
  72. }

如上面的代碼,NonReentrantLock定義了一個內部類Sync用來實現具體的鎖的操作,Sync則繼承了AQS ,由于我們實現的獨占模式的鎖,所以Sync重寫了tryAcquire\tryRelease和isHeldExclusively3個方法,另外Sync提供了newCondition這個方法用來支持條件變量。

三、源碼:

所在包:com.ruigege.ConcurrentListSouceCodeAnalysis5

https://github.com/ruigege66/ConcurrentJava

以上就是Java 基于AQS實現自定義同步器的示例的詳細內容,更多關于Java 基于AQS實現自定義同步器的資料請關注服務器之家其它相關文章!

原文鏈接:https://www.cnblogs.com/ruigege0000/p/14450174.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 青青操在线观看 | 国产在线视频第一页 | 国产在线观看人成激情视频 | poverty中国老妇人 | 国产精品边做边接电话在线观看 | 欧美猛男同志video在线 | www.国产一区二区三区 | 国产日韩欧美精品在线 | 精品久久亚洲 | 肉宠文很肉到处做1v1 | 亚洲视频久久 | 人与动人物性行为zozo共患病 | 日韩在线二区全免费 | 免费yjsp妖精com | 能免费观看的韩剧 | 美女扒开腿让男生捅 | 国产成人久久精品一区二区三区 | ffee性xxⅹ另类老妇hd | 欧美乱理伦另类视频 | 免费一级片在线观看 | 日韩中文在线 | 欧美在线一二三区 | 日本免费一区二区三区 | 深夜草莓视频 | 色哟约 | 亚洲国产欧美在线人成aaa | 99久久久久国产精品免费 | 久久中文字幕综合不卡一二区 | 古装一级无遮挡毛片免费观看 | 深夜影院深a | 国产成人精品免费视频软件 | 2021国产麻豆剧传媒剧情动漫 | 国产首页精品 | 亚洲欧美专区精品伊人久久 | 高清国语自产拍免费视频国产 | 色多多视频在线 | 男人的天堂在线观看视频不卡 | 丝袜足控免费网站xx动漫漫画 | 美女被草漫画 | 1769在线视频 | 亚洲国产自拍在线 |