通俗易懂的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源码剖析-StampedLock

通俗易懂的JUC源码剖析-FutureTask

通俗易懂的JUC源码剖析-ArrayBlockingQueue

通俗易懂的JUC源码剖析-ReentrantLock&AQS

通俗易懂的JUC源码剖析-CompletionService