【搞定Java并发编程】第16篇:队列同步器AQS源码分析之独占模式

本文深入探讨了AQS的独占模式,包括不响应中断的同步状态获取、同步状态释放、可响应中断的获取以及超时获取。通过acquire和release方法分析了线程在同步队列中的等待与唤醒机制,详细阐述了tryAcquire和tryRelease的实现逻辑。
摘要由CSDN通过智能技术生成

AQS系列文章:

1、队列同步器AQS源码分析之概要分析

2、队列同步器AQS源码分析之独占模式

3、队列同步器AQS源码分析之共享模式

4、队列同步器AQS源码分析之Condition接口、等待队列


本文主要讲解队列同步器AQS的独占模式:主要分为独占式同步状态获取(不响应中断)、独占式同步状态释放、独占式获取同步状态(响应中断)、独占式超时获取同步状态

目  录:

1、独占式同步状态获取:不响应中断

2、独占式同步状态的释放

3、独占式获取同步状态:可响应中断

4、独占式超时获取同步状态


1、独占式同步状态获取:不响应中断

通过调用同步器的acquire(int  arg)方法可以获取同步状态,该方法对中断不敏感,也是由于线程获取同步状态失败后进入同步队列中,后续对线程进行中断操作时,线程不会从同步队列中移除。

// 独占式同步状态获取与释放(不响应中断方式获取)
public final void acquire(int arg) {
    if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) {
        selfInterrupt();
    }
}

上诉代码主要完成了同步状态获取、节点构造、加入同步队列以及在同步队列中自旋等待的相关工作。

其主要逻辑是:首先调用自定义同步器实现的tryAcquire(int  arg)方法,该方法保证线程安全的获取同步状态,如果失败则构造同步节点(独占式Node.EXCLUSIVE,同一时刻只能有一个线程成功获取同步状态)并通过addWriter(Node node)方法将该节点加入到同步队列的尾部,最后调用acquireQueued(Node node, int arg)方法,使得该节点以“死循环”的方式获取同步状态。

如果获取不到则阻塞节点中的线程,而被阻塞线程的唤醒主要依靠前驱节点的出队或阻塞线程被中断来实现。

  • 第一步:tryAcquire(int arg):尝试去获取同步状态 / 锁 
// 尝试去获取同步状态(独占模式)
protected boolean tryAcquire(int arg) {
    throw new UnsupportedOperationException();
}

tryAcquire(int arg)方法需要子类去覆盖,重写里面的判断逻辑。如果获取到了同步状态则退出返回,否则生成节点加入同步队列尾部。

  • 第二步:addWaiter(Node mode):将当前线程包装成结点并添加到同步队列尾部
// 将当前线程包装成结点并添加到同步队列尾部
private Node addWaiter(Node mode) {
    // 指定持有锁的模式
    Node node = new Node(Thread.currentThread(), mode);
    // 获取同步队列尾结点引用
    Node pred = tail;
    // 如果尾结点不为空, 表明同步队列已存在结点
    if (pred != null) {
        // 1.指向当前尾结点
        node.prev = pred;
        // 2.设置当前结点为尾结点
        if (compareAndSetTail(pred, node)) {
            // 3.将旧的尾结点的后继指向新的尾结点
            pred.next = node;
            return node;
        }
    }
    // 否则表明同步队列还没有进行初始化
    enq(node);
    return node;
}

// 结点入队操作
private Node enq(final Node node) {
    for (;;) {
        // 获取同步队列尾结点引用
        Node t = tail;
        // 如果尾结点为空说明同步队列还没有初始化
        if (t == null) {
            // 初始化同步队列
            if (compareAndSetHead(new Node())) {
            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值