深入理解AQS--jdk层面管程实现【管程详解的补充】( 二 )

2.方法解析
//定义了主体的大体逻辑 , 如入队 , 如尝试加锁private Node addWaiter(Node mode) {Node node = new Node(Thread.currentThread(), mode);// Try the fast path of enq; backup to full enq on failureNode pred = tail;if (pred != null) {node.prev = pred;if (compareAndSetTail(pred, node)) {pred.next = node;return node;}}enq(node);return node;}protected final boolean compareAndSetState(int expect, int update) {// See below for intrinsics setup to support thisreturn unsafe.compareAndSwapInt(this, stateOffset, expect, update);}//模板方法的处理 , 如果子类没有实现 , 则子类中调用的话会报错//提供给子类去实现的公平与非公平的逻辑protected boolean tryAcquire(int arg) {throw new UnsupportedOperationException();}//释放锁的逻辑protected boolean tryRelease(int arg) {throw new UnsupportedOperationException();}Node类详解1.代码展示
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;//值为0 , 初始化状态 , 表示当前节点在sync队列中 , 等待着获取锁 。//CANCELLED , 值为1 , 表示当前的线程被取消;//SIGNAL , 值为-1 , 表示当前节点的后继节点包含的线程需要运行 , 也就是unpark;//CONDITION , 值为-2 , 表示当前节点在等待condition , 也就是在condition队列中;//PROPAGATE , 值为-3 , 表示当前场景下后续的acquireShared能够得以执行;volatile int waitStatus;volatile Node prev;//前驱结点volatile Node next;//后继结点volatile Thread thread; //与节点绑定的线程Node nextWaiter; // 存储condition队列中的后继节点final boolean isShared() {return nextWaiter == SHARED;}final Node predecessor() throws NullPointerException {Node p = prev;if (p == null)throw new NullPointerException();elsereturn p;}Node() {}Node(Thread thread, Node mode) {// Used by addWaiterthis.nextWaiter = mode;this.thread = thread;}Node(Thread thread, int waitStatus) { // Used by Conditionthis.waitStatus = waitStatus;this.thread = thread;}}Condition接口详解1.代码展示
//Condition用来替代synchronized锁的监视器的功能 , 而且更加灵活//一个Condition实例需要与一个lock进行绑定public interface Condition {//调用此方法的线程将加入等待队列 , 阻塞直到被通知或者线程中断void await() throws InterruptedException;//调用此方法的线程将加入等待队列 , 阻塞直到被通知(线程中断忽略)void awaitUninterruptibly();//调用此方法的线程将加入等待队列 , 阻塞直到被通知或者线程中断或等待超时long awaitNanos(long nanosTimeout) throws InterruptedException;//调用此方法的线程将加入等待队列 , 阻塞直到被通知或者线程中断或等待超时boolean await(long time, TimeUnit unit) throws InterruptedException;//调用此方法的线程将加入等待队列 , 阻塞直到被通知或者线程中断或超出指定日期boolean awaitUntil(Date deadline) throws InterruptedException;//唤醒一个等待中的线程void signal();//唤醒所以等待中的线程void signalAll();}2.发现说明
【1】在Condition中 , 用await()替换wait() , 用signal()替换notify() , 用signalAll()替换notifyAll() , 传统线程的通信方式 , Condition都可以实现 , 这里注意 , Condition是被绑定到Lock上的 , 要创建一个Lock的Condition必须用newCondition()方法 。Condition的强大之处在于 , 对于一个锁 , 我们可以为多个线程间建立不同的Condition 。如果采用Object类中的wait(), notify(), notifyAll()实现的话 , 当写入数据之后需要唤醒读线程时 , 不可能通过notify()或notifyAll()明确的指定唤醒读线程 , 而只能通过notifyAll唤醒所有线程 , 但是notifyAll无法区分唤醒的线程是读线程 , 还是写线程 。所以 , 通过Condition能够更加精细的控制多线程的休眠与唤醒 。

经验总结扩展阅读