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
- AbstractQueuedSynchronizer
- AbstractQueuedSynchronizer
- AbstractQueuedSynchronizer
- AbstractQueuedSynchronizer
- AbstractQueuedSynchronizer
- AbstractQueuedSynchronizer
- AbstractQueuedSynchronizer
- AbstractQueuedSynchronizer
- AbstractQueuedSynchronizer
- Inside AbstractQueuedSynchronizer
- Java --- AbstractQueuedSynchronizer
- 走近AbstractQueuedSynchronizer
- Java-AbstractQueuedSynchronizer
- AbstractQueuedSynchronizer分析
- AbstractQueuedSynchronizer框架
- AbstractQueuedSynchronizer初探
- AbstractQueuedSynchronizer.cancelAcquire
- JAVA-AbstractQueuedSynchronizer
- css设置透明度 (兼容所有浏览器)
- ListView底部添加加载更多按钮实现数据分页
- Android5.0免Root截屏,录屏
- OC-字典
- 【leetcode】231. Power of Two
- AbstractQueuedSynchronizer
- 设计模式之 模板模式(做练习题实例)
- 求完数
- Android设置EditText只能输入字母和数字
- 微信公众号开发系列
- js验证真实姓名
- freeswitch接入网络摄像头
- 单点登录之apacheds之springMVC下操作使用
- HDU1282 回文数猜想 (简单模拟)