java并发之AQS

打印 上一主题 下一主题

主题 808|帖子 808|积分 2424

一、简介

AQS,全称:AbstractQueuedSynchronizer,是一个JDK提供的用于构建锁、同步器等线程协作工具类的框架,内部维护FIFO双向队列(双向链表实现)。
AQS重要属性:
  1. // 表示同步状态。它既可以表示独占模式下的锁状态,也可以表示共享模式下的资源数量。通过修改state字段,可以实现多线程的独占或共享模式‌
  2. private volatile int state
  3. // 当前持有独占锁的线程
  4. private transient Thread exclusiveOwnerThread
  5. // 头节点
  6. private transient volatile Node head;
  7. // 尾节点
  8. private transient volatile Node tail;
复制代码
Node节点重要属性:
  1. // 加入队列的线程
  2. volatile Thread thread;
  3. // 前驱节点
  4. volatile Node prev;
  5. // 后继节点
  6. volatile Node next;
  7. // CANCELLED: 表示线程已经取消了对同步状态的请求。
  8. // SIGNAL: 表示线程需要被唤醒(通常是因为其他线程释放了同步状态)。
  9. // CONDITION: 表示线程正在等待某个条件。
  10. // PROPAGATE: 表示下一次共享状态的释放应该传播到其他线程。
  11. // 0: 初始状态,表示节点没有特定的状态。
  12. volatile int waitStatus;
  13. Node nextWaiter;
复制代码
AQS 在 ReentrantLock、ReentrantReadWriteLock、Semaphore、CountDownLatch、ThreadPoolExcutor 的 Worker 中都有运用(JDK 1.8),AQS 是这些类的底层原理。
二、实现自定义线程协作工具类

2.1 实现独占锁

重写AQS以下方法
  1. boolean tryAcquire(int arg)
  2. boolean tryRelease(int arg)
  3. boolean isHeldExclusively()
复制代码
调用AQS以下方法
  1. public final void acquire(int arg) {
  2.     if (!tryAcquire(arg) &&
  3.         acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
  4.         selfInterrupt();
  5. }
  6. public final boolean release(int arg) {
  7.     if (tryRelease(arg)) {
  8.         Node h = head;
  9.         if (h != null && h.waitStatus != 0)
  10.             unparkSuccessor(h);
  11.         return true;
  12.     }
  13.     return false;
  14. }
复制代码
2.2 实现共享锁

重写AQS以下方法
  1. int tryAcquireShared(int arg)
  2. boolean tryReleaseShared(int arg)
复制代码
调用AQS以下方法
  1. public final void acquireShared(int arg) {
  2.     if (tryAcquireShared(arg) < 0)
  3.         doAcquireShared(arg);
  4. }
  5. public final boolean releaseShared(int arg) {
  6.     if (tryReleaseShared(arg)) {
  7.         doReleaseShared();
  8.         return true;
  9.     }
  10.     return false;
  11. }
  12. public final void acquireSharedInterruptibly(int arg)
  13.         throws InterruptedException {
  14.     if (Thread.interrupted())
  15.         throw new InterruptedException();
  16.     if (tryAcquireShared(arg) < 0)
  17.         doAcquireSharedInterruptibly(arg);
  18. }
复制代码
2.3 示例

  1. import java.util.concurrent.TimeUnit;
  2. import java.util.concurrent.locks.AbstractQueuedSynchronizer;
  3. import java.util.concurrent.locks.Condition;
  4. import java.util.concurrent.locks.Lock;
  5. public class Test {
  6.     class MySync extends AbstractQueuedSynchronizer {
  7.         @Override
  8.         protected boolean tryAcquire(int arg) {
  9.             if (compareAndSetState(0, 1)) {
  10.                 setExclusiveOwnerThread(Thread.currentThread());
  11.                 return true;
  12.             }
  13.             return false;
  14.         }
  15.         @Override
  16.         protected boolean tryRelease(int arg) {
  17.             setExclusiveOwnerThread(null);
  18.             setState(0);
  19.             return true;
  20.         }
  21.         @Override
  22.         protected boolean isHeldExclusively() {
  23.             return getState() == 1;
  24.         }
  25.         public Condition newCondition() {
  26.             return new ConditionObject();
  27.         }
  28.     }
  29.     class MyLock implements Lock {
  30.         private MySync sync = new MySync();
  31.         @Override
  32.         public void lock() {
  33.             sync.acquire(1);
  34.         }
  35.         @Override
  36.         public void lockInterruptibly() throws InterruptedException {
  37.             sync.acquireInterruptibly(1);
  38.         }
  39.         @Override
  40.         public boolean tryLock() {
  41.             return sync.tryAcquire(1);
  42.         }
  43.         @Override
  44.         public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
  45.             return sync.tryAcquireNanos(1, unit.toNanos(time));
  46.         }
  47.         @Override
  48.         public void unlock() {
  49.             sync.release(1);
  50.         }
  51.         @Override
  52.         public Condition newCondition() {
  53.             return sync.newCondition();
  54.         }
  55.     }
  56.     public static void main(String[] args) throws Exception {
  57.         Test test = new Test();
  58.         MyLock myLock = test.new MyLock();
  59.         Thread t1 = new Thread(new Runnable() {
  60.             @Override
  61.             public void run() {
  62.                 try {
  63.                     myLock.lock();
  64.                     System.out.println(Thread.currentThread().getName() + "执行开始");
  65.                     Thread.sleep(5000L);
  66.                     System.out.println(Thread.currentThread().getName() + "执行结束");
  67.                 } catch (InterruptedException e) {
  68.                     e.printStackTrace();
  69.                 } finally {
  70.                     myLock.unlock();
  71.                 }
  72.             }
  73.         }, "t1");
  74.         Thread t2 = new Thread(new Runnable() {
  75.             @Override
  76.             public void run() {
  77.                 try {
  78.                     myLock.lock();
  79.                     System.out.println(Thread.currentThread().getName() + "执行开始");
  80.                     Thread.sleep(3000L);
  81.                     System.out.println(Thread.currentThread().getName() + "执行结束");
  82.                 } catch (InterruptedException e) {
  83.                     e.printStackTrace();
  84.                 } finally {
  85.                     myLock.unlock();
  86.                 }
  87.             }
  88.         }, "t2");
  89.         Thread t3 = new Thread(new Runnable() {
  90.             @Override
  91.             public void run() {
  92.                 try {
  93.                     myLock.lock();
  94.                     System.out.println(Thread.currentThread().getName() + "执行开始");
  95.                     Thread.sleep(1000L);
  96.                     System.out.println(Thread.currentThread().getName() + "执行结束");
  97.                 } catch (InterruptedException e) {
  98.                     e.printStackTrace();
  99.                 } finally {
  100.                     myLock.unlock();
  101.                 }
  102.             }
  103.         }, "t3");
  104.         t1.start();
  105.         t2.start();
  106.         t3.start();
  107.     }
  108. }
复制代码


  • 参考1

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

千千梦丶琪

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表