通俗易懂的JUC源码剖析-ReentrantLock&AQS
Posted 小强大人
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通俗易懂的JUC源码剖析-ReentrantLock&AQS相关的知识,希望对你有一定的参考价值。
AQS概述
大家可能对AQS听得很多,它的全称是AbstractQueuedSynchronizer,即抽象队列同步器,它是JUC包中很多同步组件的基础。先来看看它的类层次以及内部数据结构吧。
public abstract class AbstractQueuedSynchronizer
extends AbstractOwnableSynchronizer
implements java.io.Serializable {
它的父类AbstractOwnableSynchronizer提供了拥有独占锁的线程管理功能,有如下重要方法:
// 设置当前拥有独占锁的线程
protected final void setExclusiveOwnerThread(Thread thread) {
exclusiveOwnerThread = thread;
}
// 获取当前拥有独占锁的线程
protected final Thread getExclusiveOwnerThread() {
return exclusiveOwnerThread;
}
再来看AQS本身的内部结构。
关键属性:
// 头结点
private transient volatile Node head;
// 尾结点
private transient volatile Node tail;
// 锁状态
private volatile int state;
其中,Node是AQS的内部类,它用来封装线程,组成一个双向的同步队列。代码如下:
static final class Node {
// SHARED/EXCLUSIVE表示锁的模式
// 共享模式
static final Node SHARED = new Node();
// 独占模式
static final Node EXCLUSIVE = null;
// waitStatus的值之一,表示当前结点由于超时或中断取消获取锁。
static final int CANCELLED = 1;
// waitStatus的值之一,表示当前结点的后继结点需要被唤醒。
static final int SIGNAL = -1;
// waitStatus的值之一,表示当前结点处于Condition条件绑定的的等待队列中,等条件满足,当前结点会被重新移入同步队列中,等待获取锁。
static final int CONDITION = -2;
// waitStatus的值之一,表示当前结点释放共享资源时,需要把这个信息传播给其他结点,不止是它的后继结点。
static final int PROPAGATE = -3;
// 当前线程的等待状态
volatile int waitStatus;
// 当前结点的前继结点
volatile Node prev;
// 当前结点的后继结点
volatile Node next;
// 封装的线程
volatile Thread thread;
// 等待队列中的下一个等待结点
// 或者特殊值SHARED/EXCLUSIVE,用来记录是共享锁还是独占锁
Node nextWaiter;
// 判断是否共享锁
final boolean isShared() {
return nextWaiter == SHARED;
}
// 获取当前结点的前继结点
final Node predecessor() throws NullPointerException {
Node p = prev;
if (p == null)
throw new NullPointerException();
else return p;
}
Node() { // Used to establish initial head or SHARED marker
}
Node(Thread thread, Node mode) { // Used by addWaiter
this.nextWaiter = mode;
this.thread = thread;
}
Node(Thread thread, int waitStatus) { // Used by Condition
this.waitStatus = waitStatus;
this.thread = thread;
}
这个先放一放,下次再更新,感兴趣的同学记得关注哦^_^
以上是关于通俗易懂的JUC源码剖析-ReentrantLock&AQS的主要内容,如果未能解决你的问题,请参考以下文章
通俗易懂的JUC源码剖析-LinkedBlockingQueue
通俗易懂的JUC源码剖析-ArrayBlockingQueue