AQS实战以及框架源码分析

1 框架是一个抽象类,但是没有抽象方法

2 需要覆盖一些方法实现自己特定功能的锁,框架会调用这些方法做一些判断,通常返回值是boolean,下面这些都是需要自己实现,很明显它们直接抛异常,等着你实现.

protected boolean tryAcquire(int arg) {

        throw new UnsupportedOperationException();

    }

protected boolean tryRelease(int arg) {

        throw new UnsupportedOperationException();

    }


3 final方法不可以覆盖:这些是框架来调用

//acquireQueued让阻塞队列里的节点线程有机会重新获得锁,框架已经实现

//addWaiter(Node.EXCLUSIVE)把当前节点加入到队列中,框架已经实现

//获取锁失败,就把线程变成一个node加入到阻塞队列中,在阻塞队列中用死循环(自旋)完成"尝试获得锁(tryAcquire)--->park(阻塞)--->unpark(被唤醒)-->尝试获得锁-->",这里尝试获得锁必须满足当前线程节点的前一个节点是头节点,头节点代表已经获得锁的节点.因此这是默认的公平锁

//release方法只唤醒head节点的后续一个节点,如果后续一个节点代表的线程被取消,则从后往前选一个没有被取消的节点.所以并不是唤醒所有的节点.

public final void acquire(int arg) {

        if (!tryAcquire(arg) &&

            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))

            selfInterrupt();

    }

public final boolean release(int arg) {

        if (tryRelease(arg)) {

            Node h = head;

            if (h != null && h.waitStatus != 0)

                unparkSuccessor(h);

            return true;

        }

        return false;

    }

4 lock.lock(),condition.await() , lock.unlock()这是condition的用法,类似synchronised和wait的用法

5 public class ReentrantReadWriteLock  implements ReadWriteLock, java.io.Serializable.

ReentrantReadWriteLock组合aqs的抽象类syn,syn实现了acquireShared(1), acquire(1).

读锁和写锁实现lock接口,组合syn,两个都是共享一个ReentrantReadWriteLock,共享ReentrantReadWriteLock的syn,

读锁lock调用sync.acquireShared(1);, 写锁调用sync.acquire(1);

公平锁static final class FairSync extends Sync 继承Sync实现其中虚函数

static final class FairSync extends Sync {

        private static final long serialVersionUID = -2274990926593161451L;

        final boolean writerShouldBlock() {

            return hasQueuedPredecessors();

        }

        final boolean readerShouldBlock() {

            return hasQueuedPredecessors();

        }

    }

非公平锁static final class NonFairSync extends Sync 继承Sync实现其中虚函数

static final class NonfairSync extends Sync {

        private static final long serialVersionUID = -8159625535654395037L;

        final boolean writerShouldBlock() {

            return false; // writers can always barge

        }

        final boolean readerShouldBlock() {

            /* As a heuristic to avoid indefinite writer starvation,

            * block if the thread that momentarily appears to be head

            * of queue, if one exists, is a waiting writer.  This is

            * only a probabilistic effect since a new reader will not

            * block if there is a waiting writer behind other enabled

            * readers that have not yet drained from the queue.

            */

            return apparentlyFirstQueuedIsExclusive();

        }

    }

你可能感兴趣的:(AQS实战以及框架源码分析)