标签:prot color gate ctf node lock null help current
AbstractQueuedSynchronizer抽象同步队列是一个抽象类,简称AQS,是实现同步器的基础组件,并发包中锁的底层就是使用AQS实现的
AQS的数据结构:逻辑结构:双向队列,存储结构:链式存储,所以包含头尾节点head、tail及节点Node。
一、Node(静态内部类)
1、变量与构造方法
//标记线程是获取共享资源时被阻塞挂起后放入AQS队列的 static final Node SHARED = new Node(); //标记线程是获取独占资源时被挂起后放入AQS队列的 static final Node EXCLUSIVE = null; //waitStatus == 1:表示线程已取消 static final int CANCELLED = 1; //waitStatus == -1:线程需要被唤醒(与LockSupport的关联许可LockSupport.unpark) static final int SIGNAL = -1; //waitStatus == -2:线程在条件队列中等待 static final int CONDITION = -2; //waitStatus == -3释放共享资源时需要通知其他节点 static final int PROPAGATE = -3; //状态 volatile int waitStatus; //前一个节点 volatile Node prev; // volatile Node next; //后一个节点 volatile Thread thread; // Node nextWaiter; Node() { //无参构造方法 创建头结点或者共享模型节点 } 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; }
2.方法;只有两个方法
/** * Returns true if node is waiting in shared mode. */判断是否是共享模式下的节点 final boolean isShared() { return nextWaiter == SHARED; } /** * Returns previous node, or throws NullPointerException if null. * Use when predecessor cannot be null. The null check could * be elided, but is present to help the VM. * 返回pre 为空时空指针异常 * @return the predecessor of this node */ final Node predecessor() throws NullPointerException { Node p = prev; if (p == null) throw new NullPointerException(); else return p; }
二、AQS
1.变量和构造方法
//双链表头节点 延迟初始化 只能setHead修改 头结点waitStatus != Node.CANCELLED private transient volatile Node head; //双链表尾节点 延迟初始化 只能enq()入队时修改 private transient volatile Node tail; //The synchronization state.同步锁状态 private volatile int state; private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final long stateOffset; private static final long headOffset; private static final long tailOffset; private static final long waitStatusOffset; 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); } } protected AbstractQueuedSynchronizer() { }
2.方法
1).Node enq(Node node):入队方法,头尾节点的初始化;及尾插法建立链表入队。是private方法,必有封装方法
/** * 节点入队,包含头尾节点初始化 */ private Node enq(final Node node) { for (;;) { Node t = tail; if (t == null) { // Must initialize if (compareAndSetHead(new Node())) tail = head;//初始化,tail == head == new Node(); } else { node.prev = t; if (compareAndSetTail(t, node)) { t.next = node; return t;//标准的尾插法建立链表 } } } }
2. Node addWaiter(Node node):enq方法的封装,但还是private方法,封装方法分为两类:共享模式,独占模式
/** * Creates and enqueues node for current thread and given mode. * * @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared * @return the new node */ private Node addWaiter(Node mode) { Node node = new Node(Thread.currentThread(), mode); // 尾节点不为空时,初次入队尝试跳过enq方法直接入队,如果CAS失败,调用enq入队,enq方法会无限重试CAS for(;;) Node pred = tail; if (pred != null) { node.prev = pred; if (compareAndSetTail(pred, node)) { pred.next = node; return node; } } enq(node); return node; }
共享资源模式:
1)void doAcquireShared(int arg):
public final void acquireShared(int arg) { if (tryAcquireShared(arg) < 0)//尝试获取共享资源,成功直接返回,失败入阻塞队列 doAcquireShared(arg); } /** * 共享模式下获取资源,中断导致park返回中断后还原, 另有doAcquireSharedInterruptibly方法,中断导致park返回时抛出异常,结束线程 * @param arg the acquire argument */ private void doAcquireShared(int arg) { final Node node = addWaiter(Node.SHARED);//共享资源Node节点插入阻塞队列 boolean failed = true; try { boolean interrupted = false; for (;;) { final Node p = node.predecessor();
//前驱节点是头节点时,尝试获取共享资源成功后检查Node.waiterStatus<0释放资源,还原中断标志 if (p == head) { int r = tryAcquireShared(arg); if (r >= 0) { setHeadAndPropagate(node, r); p.next = null; // help GC if (interrupted) selfInterrupt(); failed = false; return; } }
if (shouldParkAfterFailedAcquire(p, node) &&//设置Node.waiterStatus == Node.SIGNAL parkAndCheckInterrupt())//LockSupport.park阻塞线程,当返回时判断是否中断引起的返回 interrupted = true; } } finally { if (failed) cancelAcquire(node); } }
AbstractQueuedSynchronizer类(AQS)
标签:prot color gate ctf node lock null help current
原文地址:https://www.cnblogs.com/wqff-biubiu/p/12173900.html