AbstractQueuedSynchronizer

来源:互联网 发布:搜片大师源码 编辑:程序博客网 时间:2024/06/05 11:47
/**自旋锁,CLH锁也是一种基于链表的可扩展、高性能、公平的自旋锁,申请线程只在本地变量上自旋, * 它不断轮询前驱的状态,如果发现前驱释放了锁就结束自旋。 * * 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架。 * * 利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础。 * * 该同步器即可以作为排他模式也可以作为共享模式,当它被定义为一个排他模式时, * 其他线程对其的获取就被阻止,而共享模式对于多个线程获取都可以成功。 */public abstract class AbstractQueuedSynchronizer    extends AbstractOwnableSynchronizer    implements java.io.Serializable {    private static final long serialVersionUID = 7373984972572414691L;    protected AbstractQueuedSynchronizer() { }    //保存着线程引用和线程状态的容器,每个线程对同步器的访问,都可以看做是队列中的一个节点。    static final class Node {        //共享模式        static final Node SHARED = new Node();        //独占模式        static final Node EXCLUSIVE = null;        //表示当前的线程被取消        static final int CANCELLED =  1;        //表示当前节点的后继节点包含的线程需要运行,也就是unpark        static final int SIGNAL    = -1;        //表示当前节点在等待condition,也就是在condition队列中        static final int CONDITION = -2;        /**         * waitStatus value to indicate the next acquireShared should         * unconditionally propagate         */        //表示当前场景下后续的acquireShared能够得以执行        static final int PROPAGATE = -3;        // 结点状态        volatile int waitStatus;        //前驱结点        volatile Node prev;        //后继结点        volatile Node next;        //如队列的当前线程        volatile Thread thread;        //存储condition队列中的后继节点        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;        }    }    //头结点    private transient volatile Node head;    //尾结点    private transient volatile Node tail;    //同步状态    private volatile int state;    protected final int getState() {        return state;    }    protected final void setState(int newState) {        state = newState;    }    //原子操作更新同步状态值    protected final boolean compareAndSetState(int expect, int update) {        // See below for intrinsics setup to support this        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);    }    //自旋时间    static final long spinForTimeoutThreshold = 1000L;    private Node enq(final Node node) {        for (;;) { //无限循环,确保结点能够成功入队列            //保存尾结点            Node t = tail;            if (t == null) { //尾结点为空,初始化                if (compareAndSetHead(new Node()))                    tail = head;            } else { //尾结点非空,已经初始化                node.prev = t;                if (compareAndSetTail(t, node)) {//原子操作将尾结点更新设置为node                    t.next = node;                    return t;//返回尾结点                }            }        }    }    //快速添加的方式往sync queue尾部添加结点    private Node addWaiter(Node mode) {        //生成结点        Node node = new Node(Thread.currentThread(), mode);        // Try the fast path of enq; backup to full enq on failure        //保存尾结点        Node pred = tail;        if (pred != null) {//尾结点非空,已经初始化            node.prev = pred;            if (compareAndSetTail(pred, node)) {//原子操作将尾结点更新设置为node                pred.next = node;                return node;//返回新生成的结点            }        }        enq(node);// 尾结点为空,或者是compareAndSetTail操作失败,则入队列        return node;    }    private void setHead(Node node) {        head = node;        node.thread = null;        node.prev = null;    }    //唤醒node后继结点的线程    private void unparkSuccessor(Node node) {        int ws = node.waitStatus;        if (ws < 0)            compareAndSetWaitStatus(node, ws, 0);//比较并且设置结点等待状态为0        Node s = node.next;        if (s == null || s.waitStatus > 0) {//后继结点为空或者其等待状态大于0,即为CANCELLED            s = null;            // 从尾结点开始从后往前开始遍历            for (Node t = tail; t != null && t != node; t = t.prev)                if (t.waitStatus <= 0)//// 找到等待状态小于等于0的结点,找到最前的状态小于等于0的结点                    s = t;        }        if (s != null)//该结点不为空,释放线程许可            LockSupport.unpark(s.thread);    }    private void doReleaseShared() {        for (;;) {            Node h = head;            if (h != null && h != tail) {// 头结点不为空并且头结点不为尾结点                int ws = h.waitStatus;                if (ws == Node.SIGNAL) {// 状态为SIGNAL                    if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))//设置h.waitStatus = 0                        continue;            // loop to recheck cases                    unparkSuccessor(h);//唤醒后继结点                }                else if (ws == 0 &&                         !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))                    continue;                // loop on failed CAS            }            if (h == head)                   // loop if head changed                break;        }    }    private void setHeadAndPropagate(Node node, int propagate) {        Node h = head; // Record old head for check below        setHead(node);        if (propagate > 0 || h == null || h.waitStatus < 0 ||            (h = head) == null || h.waitStatus < 0) {            Node s = node.next;            if (s == null || s.isShared())// 后继为空或者为共享模式                doReleaseShared();// 以共享模式进行释放        }    }    //取消继续获取锁    private void cancelAcquire(Node node) {        if (node == null)            return;        node.thread = null;        Node pred = node.prev;        while (pred.waitStatus > 0)//找到node前驱结点中最近的一个不为CANCELLED状态的结点            node.prev = pred = pred.prev;        Node predNext = pred.next;        node.waitStatus = Node.CANCELLED;        // node结点为尾结点,则设置尾结点为pred结点        if (node == tail && compareAndSetTail(node, pred)) {            compareAndSetNext(pred, predNext, null);        } else {//node结点不为尾结点,或者比较设置不成功            // If successor needs signal, try to set pred's next-link            // so it will get one. Otherwise wake it up to propagate.            int ws;            if (pred != head &&                ((ws = pred.waitStatus) == Node.SIGNAL ||                 (ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) &&                pred.thread != null) {                Node next = node.next;                //后继结点不为空并且状态小于等于0                if (next != null && next.waitStatus <= 0)                    compareAndSetNext(pred, predNext, next);//比较并设置pred.next = next            } else {                unparkSuccessor(node);//uppark node后继结点            }            node.next = node; // help GC        }    }    //获取锁失败后,检查并且更新结点状态    private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {        int ws = pred.waitStatus;//前驱结点的状态        if (ws == Node.SIGNAL) //状态为SIGNAL = -1            //可以进行park操作            return true;        if (ws > 0) { //状态为CANCELLED = 1            do {                node.prev = pred = pred.prev;            } while (pred.waitStatus > 0);//找到pred结点前面最近的一个状态不为CANCELLED的结点            pred.next = node;        } else {            //比较并设置前驱结点的状态为SIGNAL            compareAndSetWaitStatus(pred, ws, Node.SIGNAL);        }        return false;// 不能进行park操作    }    static void selfInterrupt() {        Thread.currentThread().interrupt();    }    private final boolean parkAndCheckInterrupt() {        LockSupport.park(this);//挂起线程        return Thread.interrupted();//返回线程是否被中断    }    /**    * ① 判断结点的前驱是否为head并且是否成功获取(资源)。   * ② 若步骤①均满足,则设置结点为head,之后会判断是否finally模块,然后返回。   * ③ 若步骤①不满足,则判断是否需要park当前线程,是否需要park当前线程的逻辑是判断结点的前驱结点的状态是否为SIGNAL,若是,则park当前结点,否则,不进行park操作。   * ④ 若park了当前线程,之后某个线程对本线程unpark后,并且本线程也获得机会运行。那么,将会继续进行步骤①的判断。    */    //sync结点在独占且忽略中断模式下获取锁    final boolean acquireQueued(final Node node, int arg) {        boolean failed = true;        try {            boolean interrupted = false;//中断标志            for (;;) {                //获取node结点的前驱结点                final Node p = node.predecessor();                if (p == head && tryAcquire(arg)) { //前驱为头结点并且成功获得锁                    setHead(node);//将当前结点设置为头节点                    p.next = null; // help GC                    failed = false;                    return interrupted;                }                //只有当该节点的前驱结点的状态为SIGNAL时,才可以对该结点所封装的线程进行park操作                if (shouldParkAfterFailedAcquire(p, node) &&                    parkAndCheckInterrupt())                    interrupted = true;            }        } finally {            if (failed)                cancelAcquire(node);        }    }    private void doAcquireSharedInterruptibly(int arg)        throws InterruptedException {        //添加结点代队列        final Node node = addWaiter(Node.SHARED);        boolean failed = true;        try {            for (;;) {                final Node p = node.predecessor();//获取结点的前驱结点                if (p == head) {//前驱结点为头结点                    int r = tryAcquireShared(arg);// 试图在共享模式下获取对象状态                    if (r >= 0) { // 获取成功                        setHeadAndPropagate(node, r);// 设置头结点并进行繁殖                        p.next = null; // help GC                        failed = false;                        return;                    }                }                if (shouldParkAfterFailedAcquire(p, node) &&                    parkAndCheckInterrupt())// 在获取失败后是否需要禁止线程并且进行中断检查                    throw new InterruptedException();            }        } finally {            if (failed)                cancelAcquire(node);        }    }    //以独占的方式获取锁,对中断不敏感    public final void acquire(int arg) {        //以独占的方式tryAcquire()尝试获取锁        //如果获取不到,将当前线程构造成节点Node并加入sync队列        if (!tryAcquire(arg) &&            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))            selfInterrupt();    }    public final void acquireInterruptibly(int arg)            throws InterruptedException {        if (Thread.interrupted())            throw new InterruptedException();        if (!tryAcquire(arg))            doAcquireInterruptibly(arg);    }    public final boolean tryAcquireNanos(int arg, long nanosTimeout)            throws InterruptedException {        if (Thread.interrupted())            throw new InterruptedException();        return tryAcquire(arg) ||            doAcquireNanos(arg, nanosTimeout);    }    //独占模式释放锁    public final boolean release(int arg) {        if (tryRelease(arg)) {//释放成功            Node h = head;            //头结点不为空且状态不为0            if (h != null && h.waitStatus != 0)                unparkSuccessor(h);//唤醒头结点的后继结点            return true;        }        return false;    }    public final void acquireShared(int arg) {        if (tryAcquireShared(arg) < 0)            doAcquireShared(arg);    }    public final void acquireSharedInterruptibly(int arg)            throws InterruptedException {        if (Thread.interrupted())            throw new InterruptedException();        if (tryAcquireShared(arg) < 0)            doAcquireSharedInterruptibly(arg);    }    public final boolean releaseShared(int arg) {        if (tryReleaseShared(arg)) {            doReleaseShared();            return true;        }        return false;    }    final boolean isOnSyncQueue(Node node) {        if (node.waitStatus == Node.CONDITION || node.prev == null)            return false;        if (node.next != null) // If has successor, it must be on queue            return true;        return findNodeFromTail(node);    }    final boolean transferForSignal(Node node) {        if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))            return false;        Node p = enq(node);        int ws = p.waitStatus;        if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))            LockSupport.unpark(node.thread);        return true;    }    final boolean transferAfterCancelledWait(Node node) {        if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {            enq(node);            return true;        }        while (!isOnSyncQueue(node))            Thread.yield();        return false;    }    final int fullyRelease(Node node) {        boolean failed = true;        try {            int savedState = getState();            if (release(savedState)) {                failed = false;                return savedState;            } else {                throw new IllegalMonitorStateException();            }        } finally {            if (failed)                node.waitStatus = Node.CANCELLED;        }    }    public class ConditionObject implements Condition, java.io.Serializable {        private static final long serialVersionUID = 1173984872572414699L;        /** First node of condition queue. */        //condition队列头结点        private transient Node firstWaiter;        /** Last node of condition queue. */        //condition队列尾结点        private transient Node lastWaiter;        public ConditionObject() { }        //添加新的waiter到wait队列        private Node addConditionWaiter() {            //保存尾结点            Node t = lastWaiter;            // If lastWaiter is cancelled, clean out.            if (t != null && t.waitStatus != Node.CONDITION) {// 尾结点不为空,并且尾结点的状态不为CONDITION                unlinkCancelledWaiters();//清除状态为不是CONDITION的结点                t = lastWaiter;// 将最后一个结点重新赋值给t            }            Node node = new Node(Thread.currentThread(), Node.CONDITION);            if (t == null)// 尾结点为空                firstWaiter = node;//设置头结点为node            else                t.nextWaiter = node; //设置尾结点nextWaiter域为node结点            lastWaiter = node;//尾结点指向node            return node;        }        /**         * Removes and transfers nodes until hit non-cancelled one or         * null. Split out from signal in part to encourage compilers         * to inline the case of no waiters.         * @param first (non-null) the first node on condition queue         */        private void doSignal(Node first) {            do {                if ( (firstWaiter = first.nextWaiter) == null)//该结点的nextWaiter域为null,设置尾结点为null                    lastWaiter = null;                first.nextWaiter = null;            } while (!transferForSignal(first) &&                     (first = firstWaiter) != null);// 将结点从condition队列转移到sync队列失败并且condition队列中的头结点不为空,一直循环        }        /**         * Removes and transfers all nodes.         * @param first (non-null) the first node on condition queue         */        private void doSignalAll(Node first) {            lastWaiter = firstWaiter = null;            do {                Node next = first.nextWaiter;                first.nextWaiter = null;                transferForSignal(first);// 将first结点从condition队列转移到sync队列                first = next;            } while (first != null);        }        //清除状态不是CONDITION的结点        private void unlinkCancelledWaiters() {            //保存condition队列头结点            Node t = firstWaiter;            Node trail = null;            while (t != null) {                Node next = t.nextWaiter;                if (t.waitStatus != Node.CONDITION) {// t结点的状态不为CONDTION状态                    t.nextWaiter = null;// 设置t节点的nextWaiter域为空                    if (trail == null)                        firstWaiter = next;// 重新设置condition队列的头结点                    else                        trail.nextWaiter = next;                    if (next == null)                        lastWaiter = trail;// 设置condition队列的尾结点                }                else // t结点的状态为CONDTION状态                    trail = t; // 设置trail结点                t = next;            }        }        // 唤醒一个等待线程,如果所有的线程都在等待此条件,则选择其中一个唤醒。        public final void signal() {            if (!isHeldExclusively())                throw new IllegalMonitorStateException();            Node first = firstWaiter;            if (first != null)                doSignal(first);        }        // 唤醒所有等待线程。如果所有的线程都在等待此条件,则唤醒所有线程        public final void signalAll() {            if (!isHeldExclusively())//当前线程不是锁的拥有者,抛出异常                throw new IllegalMonitorStateException();            Node first = firstWaiter;            if (first != null)                doSignalAll(first);        }         // 等待,当前线程在接到信号之前一直处于等待状态        public final void awaitUninterruptibly() {            // 将当前线程添加到等待队列            Node node = addConditionWaiter();            //释放当前线程持有的锁            int savedState = fullyRelease(node);            boolean interrupted = false;            //signal操作会将Node从Condition队列中拿出并且放入到sync等待队列中去,在不在AQS等待队列就看signal是否执行了            //如果不在AQS等待队列中,就park当前线程,如果在,就退出循环            while (!isOnSyncQueue(node)) {                LockSupport.park(this);// 阻塞当前线程                if (Thread.interrupted())// 当前线程被中断                    interrupted = true;            }            // 自旋等待尝试再次获取锁,调用acquireQueued方法            if (acquireQueued(node, savedState) || interrupted)                selfInterrupt();        }        //等待,当前线程在接到信号或被中断之前一直处于等待状态        public final void await() throws InterruptedException {            if (Thread.interrupted())                throw new InterruptedException();            Node node = addConditionWaiter();            int savedState = fullyRelease(node);            int interruptMode = 0;            while (!isOnSyncQueue(node)) {                LockSupport.park(this);                if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)                    break;            }            if (acquireQueued(node, savedState) && interruptMode != THROW_IE)                interruptMode = REINTERRUPT;            if (node.nextWaiter != null) // clean up if cancelled                unlinkCancelledWaiters();            if (interruptMode != 0)                reportInterruptAfterWait(interruptMode);        }    }}
0 0
原创粉丝点击