AbstractQueuedSynchronizer源码分析

AbstractQueuedSynchronizer是并发的基础组件,简称AQS,今天就对其部分源码一探究竟吧
推荐参考博客
AbstractQueuedSynchronizer的介绍和原理分析

public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }

上面的方法首先就是让当前线程获取锁,获取到了直接退出该方法,如果没有获取到则调用acquireQueued(addWaiter(Node.EXCLUSIVE), arg)方法,将其加入到同步队列中去。

protected boolean tryAcquire(int arg) {
        throw new UnsupportedOperationException();
    }

这个方法虽然没有设置为抽象的方法但是却不能直接使用,需要子类重写该方法。作者之所以不将其定义为抽象方法,我想主要是因为这个类的功能很多,可以使用该类写出独占或是共享式的锁,二者两种锁,并不需要重写这个类中所有的类似上面的方法,如果是抽象的方法,用不到的方法也要进行重写,这是相当不必要的。
tryAcquire独占式简单实现:

    public boolean tryAcquire(int acquires) {
        - 只有一个线程能更改该state属性,这就对应着只有一个线程可以获取锁。
更改state属性值(获取锁)失败的线程要进入同步队列中,这就对应着没有获取锁的线
程会进入堵塞队列中,等待获取锁的线程释放锁。
        if (compareAndSetState(0, 1)) {
            setExclusiveOwnerThread(Thread.currentThread());
            return true;
        }
        return false;
    }

通过简单对AQS的状态属性进行更改,实现获取锁。
其实这里很多人可能无法理解,为什么这样就是获取了锁,java中的synchronized同步锁其实就是通过对象头中的信息判断的,且jvm保证了只要一个线程可以获取锁,这里要实现锁,就是通过一个volatile成员属性,然后CAS保证原子性,对应内存语义就是锁的概念。

private Node enq(final Node node) {
        for (;;) {
            Node t = tail;
            if (t == null) { // Must initialize
                if (compareAndSetHead(new Node()))
                    tail = head;
            } else {
                node.prev = t;
                if (compareAndSetTail(t, node)) {
                    t.next = node;
                    return t;
                }
            }
        }
    }

    private Node addWaiter(Node mode) {
        - 将当前线程构造成一个节点,加入到同步队列中
        Node node = new Node(Thread.currentThread(), mode);
        Node pred = tail;
        if (pred != null) {
            node.prev = pred;
            if (compareAndSetTail(pred, node)) {
                pred.next = node;
                return node;
            }
        }
        enq(node);
        return node;
    }

对应获取锁(更改state值)失败的线程,将会执行上面的方法进入同步队列中

未完待续...写的太菜了,哈哈

你可能感兴趣的:(AbstractQueuedSynchronizer源码分析)