博客
关于我
ReentrantLock 源码分析 - AbstractQueuedSynchronizer 详解(一)
阅读量:480 次
发布时间:2019-03-06

本文共 1964 字,大约阅读时间需要 6 分钟。

前言

上一篇文章介绍了AbstractQueuedSynchronizer (AQS)的基本概念及其在Java并发编程中的作用。本文将基于JDK 8的源码,深入分析AQS及其在ReentrantLock中的应用。阅读本文前,建议了解共享锁和独占锁的基本概念。

正文

上一篇文章提到CountDownlatch、ReentrantLock、ReentrantReadWriteLock以及Semaphore等并发工具类都基于AQS实现。为了支持这些功能,AQS需要具备高度灵活和通用的功能。例如:

  • ReentrantLock(独占锁)通过调用AQS的acquire方法获取独占资源。
  • ReentrantReadWriteLock(共享锁)通过调用AQS的acquireShared方法获取共享资源。
  • 这些方法均呼吁了compareAndSetState方法来执行CAS操作。

虽然上述只是两个类的区别,但Java.util.concurrent包中包含多种工具类,因此我们无需全面理解AQS的所有功能。接下来,我们将重点分析AQS在ReentrantLock中的作用。


1. Node类

Node类是AQS的内部类,主要用于管理队列中的节点。其属性包括:

  • prev 和 next:分别表示前驱和后驱指针。
  • thread:存储当前线程标识。
  • SHARED:标记当前线程因抢夺共享资源而进入队列。
  • EXCLUSIVE:标记当前线程因抢夺独占资源而进入队列。
  • waitStatus:表示当前线程的等待状态,可选值包括CANCELLED、CONDITION、SIGNAL和PROPAGATE。

AQS是一个双向队列,队列中的元素是Node对象。


2. AQS的核心属性

AQS维护以下关键属性:

  • head 和 tail:分别指向队列的头节点和尾节点。
  • state:表示当前锁的状态。例如,在ReentrantLock中,state即为重入次数。

3. AQS的核心方法

AQS提供了几个关键方法:

  • acquire(int arg):尝试获取独占资源。当获取失败时,将当前线程放入队列并阻塞。
  • release(int arg):释放独占资源,并唤醒队列中的线程。
  • compareAndSetState(long expect, long update):通过CAS操作来更新状态。

3.1 acquire方法

acquire方法的大致逻辑如下:

public final void acquire(int arg) {    if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) {        selfInterrupt();    }}
  • tryAcquire尝试获取锁,如果成功则返回true,否则返回false。
  • acquireQueued将当前线程挂入队列并阻塞。
  • selfInterrupt在获取失败后唤醒当前线程。

3.2 release方法

release方法的大致逻辑如下:

public final boolean release(int arg) {    if (tryRelease(arg)) {        Node h = head;        if (h != null && h.waitStatus != 0) {            unparkSuccessor(h);        }        return true;    }    return false;}
  • tryRelease尝试释放锁,成功时返回true,否则返回false。
  • unparkSuccessor唤醒队列中的线程,并调用LockSupport.unpark方法。

3.3 compareAndSetState方法

compareAndSetState方法通过unsafe类的native方法实现CAS操作。例如:

protected final boolean compareAndSetState(long expect, long update) {    return unsafe.compareAndSwapLong(this, stateOffset, expect, update);}

总结

AQS是一个高度灵活的同步设施,作为许多并发工具类(如ReentrantLock)的基础。它通过双向队列管理线程,并支持CAS操作来实现高效的信号传递。当多个线程竞争锁时,未成功获取锁的线程会被放入队列,直到锁被释放并唤醒。AQS的引用使相关锁类能够支持复杂的并发场景,具体实现方式需结合各类的具体需求来定制。

转载地址:http://jgpdz.baihongyu.com/

你可能感兴趣的文章
python写下拉列表在excel,无法使用python获取Excel下拉列表(组合框)值
查看>>
python2.7安装
查看>>
Python2.7安装ncmbot时提示:Microsoft Visual C++9.0 is required
查看>>
PYTHON2.Git.1
查看>>
python20181211
查看>>
Python内存管理机制
查看>>
Python2中range 和xrange的区别??
查看>>
python2和3的区别
查看>>
python2和python3的pip版本升级
查看>>
python2和python3的区别
查看>>
python2备份交换机配置脚本
查看>>
Python3 - 在字符串格式化程序参数中使用变量
查看>>
Python3 A*寻路算法实现
查看>>
python3 grpc安装
查看>>
python3 mysql 封装多表_python3 mysql-多表查询
查看>>
python3 mysql8_Python MySQL8.0 错误:authentication plugin 'calling_sha2_password' is not supported....
查看>>
Python关键代码总览!从Zero到Hero必看的考点
查看>>
python3 robotframework+pycharm框架搭建
查看>>
Python3 shutil模块
查看>>
Python关于strftime函数详细解析 附实战代码
查看>>