Java并发来一发(七)队列同步器AQS

一、AQS简介

队列同步器AbstractQueuedSynchronizer(简称AQS)是用来构建锁或其他同步组件的基础框架,它服务的是锁的实现者。AQS有一个变量表示同步状态,通过内置的FIFO管理线程排队,基于AQS可以将同步状态管理、线程排队、等待与唤醒等操作对锁屏蔽,简化锁的实现方式。

同步器的设计是基于模板方法的,使用者需要重写同步器指定的方法,然后将同步器组合在自定义同步组件的视线中,并调用同步器提供的模板方法。AQS的模板方法包括获取和释放同步状态等。

二、AQS原理

理解AQS主要是理解同步队列管理同步状态的获取与释放两点。

1、队列同步器结构

AQS有两个节点的引用head和tail,分别指向头尾节点。

入队设置尾节点:获取同步状态(或者说获取锁)失败的线程,会被作为节点加入队列,为保证加入过程的线程安全,通过compareAndSetTail方式入队。(第一次设置头结点是在这个操作中)

出队设置头结点:由于只有一个线程能够成功获取到同步状态,因此设置头结点不需要CAS保证,只需将头节点的下一个节点设为头结点。

2、同步状态的获取与释放

获取过程调用方法acquire:

    public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }

获取成功时做两件事:一是更新同步状态+1,二是setExclusiveOwnerThread设置获得同步状态的线程为当前线程。

获取逻辑:通过调用同步器方法tryAcquire方法,尝试获取同步状态,如果获取失败,则构造同步节点,并CAS调用addWaiter方法尝试将节点加入同步队列尾部。同步队列中的节点线程调用acquireQueued方法,以死循环的方式获取同步状态。如果获取不到同步状态,则阻塞节点中的线程,唤醒线程的方式是获取同步状态成功或线程被中断。获取过程如下图:

释放过程调用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;
    }

释放成功时做两件事:一是更新同步状态-1,二是setExclusiveOwnerThread(null)设置获得同步状态的线程为null。

释放逻辑:尝试释放,如果成功则唤醒后继节点线程。

3、获取同步状态的方式

获取同步状态的方式有3种:独占式获取同步状态、共享式获取同步状态太、独占式超时获取同步状态。

三者的区别在于,独占式同一时刻只会有一个线程获得到同步状态,而共享式可以有多个线程获得同步状态。独占式超时获取同步状态,如果获取不成功,在超时后会放弃而不会一直阻塞(这也是Lock相对于synchronized增加的功能)。

 

参考资料:

《Java并发编程的艺术》

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值