最近在读canal-adpter源码的时候,源码里通过AQS+zookeeper实现了分布式锁。尝试看了一下,看不懂通过搜索锁类继承的父类才发现是AQS所以过来阅读源码。

阅读方式:直接看对应方法 点击<>可以跟代码

JUC锁框架源码阅读-AbstractQueuedSynchronizer

 

 

什么是AQS

AQS是JUC锁框架中最重要的类,通过它来实现独占锁和共享锁的。比如ReentrantLock、countDownLatch、ReentrantReadWriteLock 都是依靠AQS实现

什么是CAS 

参考https://www.cnblogs.com/LQBlog/p/11607351.html#autoid-1-0-0

CLH队列(线程同步队列)

在没有获取到锁的情况下是线程需要阻塞的,需要阻塞的线程是通过CLH队列来存储,CLH并不是直接存储线程,而是通过内部类Node来存储的

内部类Node

static final class Node {
        // 共享模式的标记
        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条件上等待阻塞.(用于Condition的await等待)
        static final int CONDITION = -2;
        // waitStatus变量的值,标志着下一个acquireShared方法线程应该被允许。(用于共享锁)
        static final int PROPAGATE = -3;

        // 标记着当前节点的状态,默认状态是0, 小于0的状态都是有特殊作用,大于0的状态表示已取消 通过volatile保证了线程的可见性
        volatile int waitStatus;

        // prev和next实现一个双向链表
        volatile Node prev;
        volatile Node next;

        // 该节点拥有的线程
        volatile Thread thread;

        // 可能有两种作用:1. 表示下一个在Condition条件上等待的节点
        // 2. 表示是共享模式或者独占模式,注意第一种情况节点一定是共享模式
        Node nextWaiter;

        // 是不是共享模式
        final boolean isShared() {
            return nextWaiter == SHARED;
        }

        // 返回前一个节点prev,如果为null,则抛出NullPointerException异常
        final Node predecessor() throws NullPointerException {
            Node p = prev;
            if (p == null)
                throw new NullPointerException();
            else
                return p;
        }

        // 用于创建链表头head,或者共享模式SHARED
        Node() {
        }

        // 使用在addWaiter方法中
        Node(Thread thread, Node mode) {
            this.nextWaiter = mode;
            this.thread = thread;
        }

        // 使用在Condition条件中
        Node(Thread thread, int waitStatus) {
            this.waitStatus = waitStatus;
            this.thread = thread;
        }
    }
View Code

相关文章: