美文网首页工作生活
J.U.C之AQS:源码解析-核心属性

J.U.C之AQS:源码解析-核心属性

作者: 贪睡的企鹅 | 来源:发表于2019-07-04 21:31 被阅读0次

    AQS 核心属性

    public abstract class AbstractQueuedSynchronizer
    
        extends AbstractOwnableSynchronizer
        implements java.io.Serializable {
    
        private static final long serialVersionUID = 7373984972572414691L;
    
        /**
         * 同步队列头节点
         */
        private transient volatile Node head;
    
    
        /**
         * 同步队列尾节点
         */
        private transient volatile Node tail;
    
    
        /**
         * 同步状态
         */
        private volatile int state;
        
         /**
         * 状态在内存中的偏移位置
         */
        private static final long stateOffset;
        /**
         * 同步队列头节点在内存中的偏移位置
         */
        private static final long headOffset;
        /**
         * 同步队列尾节点在内存中的偏移位置
         */
        private static final long tailOffset;
        /**
         * 节点等待状态在内存中的偏移位置
         */
        private static final long waitStatusOffset;
        /**
         * 节点next节点在内存中的偏移位置
         */
        private static final long nextOffset;
    
        static {
            try {
                stateOffset = unsafe.objectFieldOffset
                    (AbstractQueuedSynchronizer.class.getDeclaredField("state"));
                headOffset = unsafe.objectFieldOffset
                    (AbstractQueuedSynchronizer.class.getDeclaredField("head"));
                tailOffset = unsafe.objectFieldOffset
                    (AbstractQueuedSynchronizer.class.getDeclaredField("tail"));
                waitStatusOffset = unsafe.objectFieldOffset
                    (Node.class.getDeclaredField("waitStatus"));
                nextOffset = unsafe.objectFieldOffset
                    (Node.class.getDeclaredField("next"));
    
            } catch (Exception ex) { throw new Error(ex); }
        }
    
        /**
         * 使用CAS 初始化同步对了头节点
         */
        private final boolean compareAndSetHead(Node update) {
            return unsafe.compareAndSwapObject(this, headOffset, null, update);
        }
    
        /**
         * 使用CAS,更新同步队列的头节点
         */
        private final boolean compareAndSetTail(Node expect, Node update) {
            return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
        }
    
        /**
         * 使用CAS 更新节点中等待状态waitStatus
         */
        private static final boolean compareAndSetWaitStatus(Node node,
                                                             int expect,
                                                             int update) {
            return unsafe.compareAndSwapInt(node, waitStatusOffset,
                                            expect, update);
        }
    
        /**
         * 使用CAS 更新节点中next
         */
        private static final boolean compareAndSetNext(Node node,
                                                       Node expect,
                                                       Node update) {
            return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
        }
        
        ....省略
        
    

    AQS 内部提供了一个内部类.用来作为同步队列和等待队列的节点对象.
    不同队列的节点.其使用的属性和含义是不同的

    static final class Node {
        /** 共享 */
        static final Node SHARED = new Node();
    
        /** 独占 */
        static final Node EXCLUSIVE = null;
    
        /**
         * 双向同步队列节点时使用,因为超时或者中断,节点会被设置为取消状态,被取消的节点时不会参与到竞争中的,他会一直保持取消状态不会转变为其他状态;
         */
        static final int CANCELLED =  1;
    
        /**
         * 双向同步队列节点时使用,后继节点的线程处于等待状态.
         * 而当前节点的线程如果释放了同步状态或者被取消,将会通知后继节点,使后继节点的线程得以运行
         */
        static final int SIGNAL    = -1;
    
        /**
         * 单向等待队列节点时使用,等待节点需要被唤醒
         */
        static final int CONDITION = -2;
    
        /**
         * 双向同步队列节点时使用,共享模式释放时,会将节点设置为此状态,并一直传播通知后续节点停止阻塞。尝试获取锁。
         */
        static final int PROPAGATE = -3;
    
        /** 等待状态 */
        volatile int waitStatus;
    
        /** 双向同步队列节点时使用,前置节点指针 */
        volatile Node prev;
    
        /** 双向同步队列节点时使用,后置节点指针 */
        volatile Node next;
    
        /** 获取同步状态的线程 */
        volatile Thread thread;
    
        /** 单项等待队列节点时使用,后置节点指针**/
        Node nextWaiter;
    
    
        //是否时CLH队列的节点同时时共享式获取同步状态
        final boolean isShared() {
            return nextWaiter == SHARED;
        }
    
        //获取当前节点的前置节点
        final Node predecessor() throws NullPointerException {
            Node p = prev;
            if (p == null)
                throw new NullPointerException();
            else
                return p;
        }
    
        Node() {
        }
        //创建同步队列节点,node传入Node.SHARED或Node.EXCLUSIVE
        Node(Thread thread, Node mode) {
            this.nextWaiter = mode;
            this.thread = thread;
        }
    
        //创建等待队列节点,waitStatus传入Node.CONDITION
        Node(Thread thread, int waitStatus) {
            this.waitStatus = waitStatus;
            this.thread = thread;
        }
    }
    

    相关文章

      网友评论

        本文标题:J.U.C之AQS:源码解析-核心属性

        本文链接:https://www.haomeiwen.com/subject/yikrhctx.html