工作生活

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

2019-07-04  本文已影响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;
    }
}
上一篇下一篇

猜你喜欢

热点阅读