博客
关于我
AQS源码分析一(公平独占锁)
阅读量:797 次
发布时间:2023-03-28

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

AbstractQueueSynchronizer(AQS)分析

在分析Java并发包java.util.concurrent源码时,AbstractQueueSynchronizer(简称AQS)是一个不可或缺的核心组件,它是ReentrantLockCountDownLatchSemaphore等多个并发工具类的基础。通过深入分析ReentrantLock的公平锁实现,我们可以更好地理解AQS的工作原理。


AQS的结构

AQS主要维护以下几个关键属性:

  • head:表示当前持有锁的线程,或者阻塞队列的首节点。
  • tail:阻塞队列的末尾节点。
  • state:表示锁的占有次数,值为0时表示锁未被占有,值大于0时表示有线程正在占用锁。
  • exclusiveOwnerThread:表示当前独占锁的线程。
  • AQS的阻塞队列采用的是FIFO(先进先出)的方式,每个线程被包装成一个Node实例,通过prevnext指针形成一个链表。每个节点还包含waitStatus,用于表示线程的等待状态。


    AQS节点(Node)结构

    每个节点包含以下属性:

    • thread:等待的线程。
    • waitStatus:等待状态,取值为:
      • CANCELLED(1):线程取消了对锁的等待。
      • SIGNAL(-1):当前节点需要被唤醒,后续节点的线程可以无条件获取锁。
      • CONDITION(-2):线程正等待在条件上(本文不分析条件)。
      • PROPAGATE(-3):下一个获取共享锁的线程应无条件传播。
    • prev:前驱节点。
    • next:后继节点。

    ReentrantLock的使用方式

    一个典型的ReentrantLock使用示例:

    public class OrderService {
    private static final ReentrantLock reentrantLock = new ReentrantLock(true);
    public void createOrder() {
    reentrantLock.lock();
    try {
    // 业务逻辑
    } finally {
    reentrantLock.unlock();
    }
    }
    }

    ReentrantLock内部通过Sync内部类实现锁机制,Sync有两个实现:FairSync(公平锁)和NonfairSync(非公平锁)。这里我们聚焦于FairSync


    线程抢锁过程

  • tryAcquire(int arg)

    • 试图直接获取锁。
    • 如果成功,state增加,线程继续执行。
    • 如果失败,线程挂入阻塞队列。
  • acquireQueued(Node node, int arg)

    • 将线程插入阻塞队列。
    • 如果队列为空,初始化头节点并将线程插入队列。
    • 如果队列不为空,线程插入队尾。
  • parkAndCheckInterrupt()

    • 挂起当前线程,等待被唤醒。
    • 检查线程是否被中断。
  • shouldParkAfterFailedAcquire(Node pred, Node node)

    • 确定是否需要挂起当前线程。
    • 如果前驱节点的waitStatusSIGNAL,挂起当前线程。
    • 否则,继续寻找可以唤醒的节点。
  • unparkSuccessor(Node node)

    • 唤醒后继节点,继续争夺锁。

  • 线程释放锁

  • release(int arg)

    • 尝试释放锁。
    • 如果成功,唤醒队列的对头节点,继续处理。
  • tryRelease(int releases)

    • 检查是否由当前线程持有锁。
    • 如果是,释放锁并唤醒后继节点。

  • 总结

    在并发环境下,ReentrantLock依赖于AQS来管理锁状态、维护等待队列和唤醒机制。AQS通过stateheadtailNode节点实现锁的获取和释放,确保线程能够高效地竞争和占有锁资源。通过分析ReentrantLock的实现,我们可以更深入地理解AQS的工作原理及其在并发编程中的重要性。

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

    你可能感兴趣的文章
    Objective-C实现k nearest neighbours k最近邻分类算法(附完整源码)
    查看>>
    Objective-C实现k-Means算法(附完整源码)
    查看>>
    Objective-C实现k-nearest算法(附完整源码)
    查看>>
    Objective-C实现Knapsack problem背包问题算法(附完整源码)
    查看>>
    Objective-C实现knapsack背包问题算法(附完整源码)
    查看>>
    Objective-C实现knapsack背包问题算法(附完整源码)
    查看>>
    Objective-C实现knight tour骑士之旅算法(附完整源码)
    查看>>
    Objective-C实现KNN算法(附完整源码)
    查看>>
    Objective-C实现koch snowflake科赫雪花算法(附完整源码)
    查看>>
    Objective-C实现KPCA(附完整源码)
    查看>>
    Objective-C实现kth order statistick阶统计量算法(附完整源码)
    查看>>
    Objective-C实现LRU 缓存算法(附完整源码)
    查看>>
    Objective-C实现lstm prediction预测算法(附完整源码)
    查看>>
    Objective-C实现Luhn (Mod 10)Algorithm算法(附完整源码)
    查看>>
    Objective-C实现max subarray sum最大子数组和算法(附完整源码)
    查看>>
    Objective-C实现MaximumSubarray最大子阵列(动态规划解决方案)算法(附完整源码)
    查看>>
    Objective-C实现max_heap最大堆算法(附完整源码)
    查看>>
    Objective-C实现md5算法(附完整源码)
    查看>>
    Objective-C实现memoization优化技术算法(附完整源码)
    查看>>
    Objective-C实现memset函数功能(附完整源码)
    查看>>