深入浅出AQS源码解读

1.AQS简介

Java并发编程核心在于java.concurrent.util包而juc当中的大多数同步器实现都是围绕着共同的基础行为,比如等待队列、条件队列、独占获取、共享获取等,而这个行为的抽象就是基于AbstractQueuedSynchronizer简称AQS,AQS定义了一套多线程访问共享资源的同步器框架,是一个依赖状态(state)的同步器。

2.AQS特性

AQS具备特性:阻塞等待队列,共享/独占,公平/非公平,可重入,允许中断

3.AQS的组成

四个个成员变量 
  private transient Thread exclusiveOwnerThread; 独占模式下的当前线程
  private transient volatile Node head;  队列的头部指针
  private transient volatile Node tail;  队列的尾部指针
  private volatile int state; 
一个内部类
  static final class Node {
   模式
    static final Node SHARED = new Node();  共享模式
    static final Node EXCLUSIVE = null; 独占模式
    信号量-线程的生命状态
    static final int CANCELLED =  1;  出现异常
    static final int SIGNAL    = -1;  可被唤醒,同步队列中通知后继节点
    static final int CONDITION = -2;  条件等待
    static final int PROPAGATE = -3; 传播 Semaphore 共享模式下
    volatile int waitStatus; 

	链表指针
    volatile Node prev;
    volatile Node next;
    Node nextWaiter;
    节点数据(线程)
	volatile Thread thread;

以上属性在ReentrantLock,Semaphore等并发工具下都有不同使用方式。

4.如何加锁

AQS里面通过一个状态同步器来加锁


 	/**
     * PS : 加锁的次数
     * 同步资源状态
     */
    private volatile int state;

同一个线程每次加锁都是对state+1,如果要保证并发安全就需要使用CAS+自旋+volatile修饰

5.没有抢到锁的线程到哪里去了

	//双向链表构建的队列
	static final class Node {
	volatile Node prev;
	volatile Node next;
	volatile Thread thread;
	}

上面提到的node节点构建的FIFO队列,就是在lock方法加锁时候,用来保存没有抢到锁的阻塞线程,以及unlock方法从头开始根据信号量去唤醒阻塞的线程。

6.总结

通过对AbstractQueuedSynchronizer类的了解,以及如何加锁解锁,线程的去向问题,对AQS有一个基本了解,保证并发主要通过state,node,CAS,volatile搭配。下面画一张图更形象的了解。后面再写reentrantlock

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值