AQS框架源码解析

本文详细分析了AQS(AbstractQueuedSynchronizer)的内部机制,包括其独占锁和共享锁的实现方式。AQS是Java并发编程中重要的同步组件,用于构建锁和其他同步器。文章介绍了state字段、Unsafe类、Node类的作用以及acquire()、release()、acquireShared()、releaseShared()等关键方法的实现细节。通过对AQS源码的解析,读者可以深入理解Java并发编程底层的同步机制。
摘要由CSDN通过智能技术生成

前言:

这是我参加工作之后,第一次开始写博客,我也不知道自己是怎么了,就突然想在网上沉淀点自己的东西,可能是平时在网上拿来主义太多,让我有点不太好意思吧。也可能是最近出去面试了几家公司,发现自己这两年都是在业务代码,对于底层的沉淀太少,虽然业务代码对我来说,没什么问题,但是只要涉及到底层的东西,我就会哑口无言,才让我痛下决心,一定要沉淀点属于自己的东西。不管怎么样,今天开始了这个博客,希望自己能够坚持住,保持自己的初心,持续更新技术和自己生活中的乐趣。共勉!!!

一. AQS框架介绍:

AQS就是我们在JUC包下面的AbstractQueuedSynchronizer,它的全名叫做抽象队列同步器,是用来构建锁或者其他同步器的基础组件。像我们平时使用到的ReentrantLock、Semaphore、CountDownLatch、ReentrantReadWriteLock等,在组件的底层都是继承了同步器。

好的废话不多说,开始今天的猪脚,也就是AbstractQueuedSynchronizer源码分析:

AbstractQueuedSynchronizer实际上是由state和FIFO同步等待队列组成的,线程都会进入到这个等待队列中,等待消费消息,同时这个state是用volatile修饰的,也就是对于state的修改,都会同步到内存中,保持前后的一致性。

1.1.AbstractQueuedSynchronizer继承关系如下图:

AbstractQueuedSynchronizer继承关系
从上图可以看出AbstractQueuedSynchronizer继承AbstarctOwnableSynchronizer,AbstarctOwnableSynchronizer是底层的一个基础类,是一个同步器。
下面我们来看下AbstractOwnableSynchronizer源码:

//AbstractOwnableSynchronizer是抽象同步器的基础类
public abstract class AbstractOwnableSynchronizer
    implements java.io.Serializable {

	    private static final long serialVersionUID = 3737899427754241961L;
	
	    protected AbstractOwnableSynchronizer() { }
	
		//设置同步占用线程(transient反系列化的时候,不会出现这个对象)
	    private transient Thread exclusiveOwnerThread;
	
		//设置当前拥有独占的线程,从注释中知道,当参数为null的时候,表示线程没有访问权,
	    protected final void setExclusiveOwnerThread(Thread thread) {
	        exclusiveOwnerThread = thread;
	    }
	
		//返回由setExclusiveOwnerThread所设置的线程,如果没有设置,则返回null。该方法不会强制执行任何同步或volatile字段访问。
	    protected final Thread getExclusiveOwnerThread() {
	        return exclusiveOwnerThread;
	    }
}

二. AbstractQueuedSynchronizer架构:

2.1.state赋值方法:

讲完了AbstractoOwnerSynchronizer的源码,下面让我们一起来看下AbstractQueuedSynchronizer的实现原理吧。设置给state赋值的方式有三种分别是:
setState(): 获取当前同步状态
getState(): 设置当前同步状态
compareAndSetState(): 使用CAS设置当前状态,该方法能够保证状态设置的原子性。
其中前面两个就不用解释了,我在这里着重说下第三个吧,也就是compareAndSetState(int expect, int update), 在这里的意思是:如果当前状态值等于预期值,那么自动将同步状态更新为给定的状态值。
这里先来看下compareAndSetState(int expect, int update)的源码:

protected final boolean compareAndSetState(int expect, int update) {
        // See below for intrinsics setup to support this
        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
    }

可以看到这个方法底层是调用了unsafe类的方法这里我就不深究unsafe类,简单说下这个类的作用:

2.2.Unsafe类的作用

sun.misc.Unsafe()类的作用:
1. 用于扩展java语言的能力,便于在最高层(java层)实现稍底层(C语言)需要实现的东西。
2. 在这里主要为了设置CAS的头结点、CAS的尾节点、CAS的设置每一个节点的waitStatus值,CAS的设置每一个next节点的值。

好的,看到这里,前面的铺垫已经说完了,我们开始下面的分析:
AQS底层有两个同步器,分别是独占(Exclusive, 独占锁,只有一个线程能执行,如ReentrantLock)和共享(share,分享锁,可以同时运行多个线程,如Semaphore/CountDownLatch)。独占锁就是在同一时刻只能有一个线程获取到锁,而其他获取锁的线程只能处于同步队列中等待,只能获取锁的线程释放了锁,后续的线程才能够获取锁。

2.2.1. 同步器实现的主要方法:

AQS的底层同步器主要是实现下面几个方法分别是:

//该线程是否正在独占资源,只有用到condition的时候,才会去使用它
protected boolean isHeldExclusively() {
        throw new UnsupportedOperationException();
    }

//独占方式,尝试去获取独占资源,成功返回true,失败返回false
protected boolean tryAcquire(int arg) {
        throw new UnsupportedOperationException();
    }

//独占方式,尝试去释放独占资源,成功返回true,失败返回false
protected boolean tryRelease(int arg) {
        throw new UnsupportedOperationException();
    }

//共享方式,尝试去获取资源,负数表示失败;零表示成功,但是没有可用资源;正数表示成功,还有可用资源。
protected int tryAcquireShared(int arg) {
        throw new UnsupportedOperationException();
    }

//共享方式,尝试去释放资源,如果释放后允许唤醒后续的节点,则返回true,否则返回false。
protected boolean tryReleaseShared(int arg) {
        throw new UnsupportedOperationException();
    }

同步器一般要么是独占方式,要么是共享方式,也就是tryAcquire()\tryRelease()和tryAcquireShared()\tryReleaseShared()一起使用,但是也有把独占和共享放在一起使用,如ReentantWriteAndReadLock 读写锁。

2.3. Node类的作用

在分析的AbstractQueuedSynchronizer的时候,发现底层有一个Node类,那么这个内部类主要是做什么呢?
通过查阅资料发现,这个类主要用下面几个作用:
1. 是等待队列的Node类
2. 是线程AQS底层CAS关键内部类。
3. 关键节点waitStatus状态在Node类中实现,比如:cancelled/signal/condition/propagate。

这几个关键节点的意思如下:
"CANCELLED": 1
暗示一个线程被撤销
节点被撤销通常都是因为超时或者被中断,进入这个接口后意味着结束状态,进入该状态后节点将不会再变成。

"SIGNAL" : -1
暗示后续线程不需要被阻塞,进入等待唤醒状态的后续结点
当其前续节点调用了方法(release()或者cancel())后,应该使得其后续节点发生移动。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值