image.png

1、非公平锁实现原理

加锁解锁流程 先从构造器开始看,默认为非公平锁实现

  1. public ReentrantLock() {
  2. sync = new NonfairSync();
  3. }

NonfairSync 继承自 AQS
没有竞争时
image.png
第一个竞争出现时
image.png
Thread-1 执行了

  1. CAS 尝试将 state 由 0 改为 1,结果失败
  2. 进入 tryAcquire 逻辑,这时 state 已经是1,结果仍然失败
  3. 接下来进入 addWaiter 逻辑,构造 Node 队列
    图中黄色三角表示该 Node 的 waitStatus 状态,其中 0 为默认正常状态
    Node 的创建是懒惰的
    其中第一个 Node 称为 Dummy(哑元)或哨兵,用来占位,并不关联线程

image.png
当前线程进入 acquireQueued 逻辑

  1. acquireQueued 会在一个死循环中不断尝试获得锁,失败后进入 park 阻塞
  2. 如果自己是紧邻着 head(排第二位),那么再次 tryAcquire 尝试获取锁,当然这时 state 仍为 1,失败
  3. 进入 shouldParkAfterFailedAcquire 逻辑,将前驱 node,即 head 的 waitStatus 改为 -1,这次返回 false
  4. shouldParkAfterFailedAcquire 执行完毕回到 acquireQueued ,再次 tryAcquire 尝试获取锁,当然这时 state 仍为 1,失败
  5. 当再次进入 shouldParkAfterFailedAcquire 时,这时因为其前驱 node 的 waitStatus 已经是 -1,这次返回 true
  6. 进入 parkAndCheckInterrupt, Thread-1 park(灰色表示)

image.png
image.png
image.png
Thread-0 释放锁,进入 tryRelease 流程,如果成功

  • 设置 exclusiveOwnerThread 为 null
  • state = 0

image.png
当前队列不为 null,并且 head 的 waitStatus = -1,进入 unparkSuccessor 流程
找到队列中离 head 最近的一个 Node(没取消的),unpark 恢复其运行,本例中即为 Thread-1
回到 Thread-1 的 acquireQueued 流程
image.png
如果加锁成功(没有竞争),会设置

  • exclusiveOwnerThread 为 Thread-1,state = 1
  • head 指向刚刚 Thread-1 所在的 Node,该 Node 清空 Thread
  • 原本的 head 因为从链表断开,而可被垃圾回收

    如果这时候有其它线程来竞争(非公平的体现),例如这时有 Thread-4 来了
    image.png
    如果不巧又被 Thread-4 占了先

  • Thread-4 被设置为 exclusiveOwnerThread,state = 1

  • Thread-1 再次进入 acquireQueued 流程,获取锁失败,重新进入 park 阻塞

1、 加锁源码

  1. // Sync 继承自 AQS
  2. static final class NonfairSync extends Sync {
  3. private static final long serialVersionUID = 7316153563782823691L;
  4. // 加锁实现
  5. final void lock() {
  6. // 首先用 cas 尝试(仅尝试一次)将 state 从 0 改为 1, 如果成功表示获得了独占锁
  7. if (compareAndSetState(0, 1))
  8. setExclusiveOwnerThread(Thread.currentThread());
  9. else
  10. // 如果尝试失败,进入 ㈠
  11. acquire(1);
  12. }
  13. // ㈠ AQS 继承过来的方法, 方便阅读, 放在此处
  14. public final void acquire(int arg) {
  15. // ㈡ tryAcquire
  16. if (
  17. !tryAcquire(arg) &&
  18. // 当 tryAcquire 返回为 false 时, 先调用 addWaiter ㈣, 接着 acquireQueued ㈤
  19. acquireQueued(addWaiter(Node.EXCLUSIVE), arg)
  20. ) {
  21. selfInterrupt();
  22. }
  23. }
  24. // ㈡ 进入 ㈢
  25. protected final boolean tryAcquire(int acquires) {
  26. return nonfairTryAcquire(acquires);
  27. }
  28. // ㈢ Sync 继承过来的方法, 方便阅读, 放在此处
  29. final boolean nonfairTryAcquire(int acquires) {
  30. final Thread current = Thread.currentThread();
  31. int c = getState();
  32. // 如果还没有获得锁
  33. if (c == 0) {
  34. // 尝试用 cas 获得, 这里体现了非公平性: 不去检查 AQS 队列
  35. if (compareAndSetState(0, acquires)) {
  36. setExclusiveOwnerThread(current);
  37. return true;
  38. }
  39. }
  40. // 如果已经获得了锁, 线程还是当前线程, 表示发生了锁重入
  41. else if (current == getExclusiveOwnerThread()) {
  42. // state++
  43. int nextc = c + acquires;
  44. if (nextc < 0) // overflow
  45. throw new Error("Maximum lock count exceeded");
  46. setState(nextc);
  47. return true;
  48. }
  49. // 获取失败, 回到调用处
  50. return false;
  51. }
  52. // ㈣ AQS 继承过来的方法, 方便阅读, 放在此处
  53. private Node addWaiter(Node mode) {
  54. // 将当前线程关联到一个 Node 对象上, 模式为独占模式
  55. Node node = new Node(Thread.currentThread(), mode);
  56. // 如果 tail 不为 null, cas 尝试将 Node 对象加入 AQS 队列尾部
  57. Node pred = tail;
  58. if (pred != null) {
  59. node.prev = pred;
  60. if (compareAndSetTail(pred, node)) {
  61. // 双向链表
  62. pred.next = node;
  63. return node;
  64. }
  65. }
  66. // 尝试将 Node 加入 AQS, 进入 ㈥
  67. enq(node);
  68. return node;
  69. }
  70. // ㈥ AQS 继承过来的方法, 方便阅读, 放在此处
  71. private Node enq(final Node node) {
  72. for (;;) {
  73. Node t = tail;
  74. if (t == null) {
  75. // 还没有, 设置 head 为哨兵节点(不对应线程,状态为 0)
  76. if (compareAndSetHead(new Node())) {
  77. tail = head;
  78. }
  79. } else {
  80. // cas 尝试将 Node 对象加入 AQS 队列尾部
  81. node.prev = t;
  82. if (compareAndSetTail(t, node)) {
  83. t.next = node;
  84. return t;
  85. }
  86. }
  87. }
  88. }
  89. // ㈤ AQS 继承过来的方法, 方便阅读, 放在此处
  90. final boolean acquireQueued(final Node node, int arg) {
  91. boolean failed = true;
  92. try {
  93. boolean interrupted = false;
  94. for (;;) {
  95. final Node p = node.predecessor();
  96. // 上一个节点是 head, 表示轮到自己(当前线程对应的 node)了, 尝试获取
  97. if (p == head && tryAcquire(arg)) {
  98. // 获取成功, 设置自己(当前线程对应的 node)为 head
  99. setHead(node);
  100. // 上一个节点 help GC
  101. p.next = null;
  102. failed = false;
  103. // 返回中断标记 false
  104. return interrupted;
  105. }
  106. if (
  107. // 判断是否应当 park, 进入 ㈦
  108. shouldParkAfterFailedAcquire(p, node) &&
  109. // park 等待, 此时 Node 的状态被置为 Node.SIGNAL ㈧
  110. parkAndCheckInterrupt()
  111. ) {
  112. interrupted = true;
  113. }
  114. }
  115. } finally {
  116. if (failed)
  117. cancelAcquire(node);
  118. }
  119. }
  120. // ㈦ AQS 继承过来的方法, 方便阅读, 放在此处
  121. private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
  122. // 获取上一个节点的状态
  123. int ws = pred.waitStatus;
  124. if (ws == Node.SIGNAL) {
  125. // 上一个节点都在阻塞, 那么自己也阻塞好了
  126. return true;
  127. }
  128. // > 0 表示取消状态
  129. if (ws > 0) {
  130. // 上一个节点取消, 那么重构删除前面所有取消的节点, 返回到外层循环重试
  131. do {
  132. node.prev = pred = pred.prev;
  133. } while (pred.waitStatus > 0);
  134. pred.next = node;
  135. } else {
  136. // 这次还没有阻塞
  137. // 但下次如果重试不成功, 则需要阻塞,这时需要设置上一个节点状态为 Node.SIGNAL
  138. compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
  139. }
  140. return false;
  141. }
  142. // ㈧ 阻塞当前线程
  143. private final boolean parkAndCheckInterrupt() {
  144. LockSupport.park(this);
  145. return Thread.interrupted();
  146. }
  147. }

2、 解锁源码

  1. // Sync 继承自 AQS
  2. static final class NonfairSync extends Sync {
  3. // 解锁实现
  4. public void unlock() {
  5. sync.release(1);
  6. }
  7. // AQS 继承过来的方法, 方便阅读, 放在此处
  8. public final boolean release(int arg) {
  9. // 尝试释放锁, 进入 ㈠
  10. if (tryRelease(arg)) {
  11. // 队列头节点 unpark
  12. Node h = head;
  13. if (
  14. // 队列不为 null
  15. h != null &&
  16. // waitStatus == Node.SIGNAL 才需要 unpark
  17. h.waitStatus != 0
  18. ) {
  19. // unpark AQS 中等待的线程, 进入 ㈡
  20. unparkSuccessor(h);
  21. }
  22. return true;
  23. }
  24. return false;
  25. }
  26. // ㈠ Sync 继承过来的方法, 方便阅读, 放在此处
  27. protected final boolean tryRelease(int releases) {
  28. // state--
  29. int c = getState() - releases;
  30. if (Thread.currentThread() != getExclusiveOwnerThread())
  31. throw new IllegalMonitorStateException();
  32. boolean free = false;
  33. // 支持锁重入, 只有 state 减为 0, 才释放成功
  34. if (c == 0) {
  35. free = true;
  36. setExclusiveOwnerThread(null);
  37. }
  38. setState(c);
  39. return free;
  40. }
  41. // ㈡ AQS 继承过来的方法, 方便阅读, 放在此处
  42. private void unparkSuccessor(Node node) {
  43. // 如果状态为 Node.SIGNAL 尝试重置状态为 0
  44. // 不成功也可以
  45. int ws = node.waitStatus;
  46. if (ws < 0) {
  47. compareAndSetWaitStatus(node, ws, 0);
  48. }
  49. // 找到需要 unpark 的节点, 但本节点从 AQS 队列中脱离, 是由唤醒节点完成的
  50. Node s = node.next;
  51. // 不考虑已取消的节点, 从 AQS 队列从后至前找到队列最前面需要 unpark 的节点
  52. if (s == null || s.waitStatus > 0) {
  53. s = null;
  54. for (Node t = tail; t != null && t != node; t = t.prev)
  55. if (t.waitStatus <= 0)
  56. s = t;
  57. }
  58. if (s != null)
  59. LockSupport.unpark(s.thread);
  60. }
  61. }

2、 可重入原理

  1. static final class NonfairSync extends Sync {
  2. // ...
  3. // Sync 继承过来的方法, 方便阅读, 放在此处
  4. final boolean nonfairTryAcquire(int acquires) {
  5. final Thread current = Thread.currentThread();
  6. int c = getState();
  7. if (c == 0) {
  8. if (compareAndSetState(0, acquires)) {
  9. setExclusiveOwnerThread(current);
  10. return true;
  11. }
  12. }
  13. // 如果已经获得了锁, 线程还是当前线程, 表示发生了锁重入
  14. else if (current == getExclusiveOwnerThread()) {
  15. // state++
  16. int nextc = c + acquires;
  17. if (nextc < 0) // overflow
  18. throw new Error("Maximum lock count exceeded");
  19. setState(nextc);
  20. return true;
  21. }
  22. return false;
  23. }
  24. // Sync 继承过来的方法, 方便阅读, 放在此处
  25. protected final boolean tryRelease(int releases) {
  26. // state--
  27. int c = getState() - releases;
  28. if (Thread.currentThread() != getExclusiveOwnerThread())
  29. throw new IllegalMonitorStateException();
  30. boolean free = false;
  31. // 支持锁重入, 只有 state 减为 0, 才释放成功
  32. if (c == 0) {
  33. free = true;
  34. setExclusiveOwnerThread(null);
  35. }
  36. setState(c);
  37. return free;
  38. }
  39. }

3、可打断原理

不可打断模式

在此模式下,即使它被打断,仍会驻留在 AQS 队列中,一直要等到获得锁后方能得知自己被打断了

  1. // Sync 继承自 AQS
  2. static final class NonfairSync extends Sync {
  3. // ...
  4. private final boolean parkAndCheckInterrupt() {
  5. // 如果打断标记已经是 true, 则 park 会失效
  6. LockSupport.park(this);
  7. // interrupted 会清除打断标记
  8. return Thread.interrupted();
  9. }
  10. final boolean acquireQueued(final Node node, int arg) {
  11. boolean failed = true;
  12. try {
  13. boolean interrupted = false;
  14. for (;;) {
  15. final Node p = node.predecessor();
  16. if (p == head && tryAcquire(arg)) {
  17. setHead(node);
  18. p.next = null;
  19. failed = false;
  20. // 还是需要获得锁后, 才能返回打断状态
  21. return interrupted;
  22. }
  23. if (
  24. shouldParkAfterFailedAcquire(p, node) &&
  25. parkAndCheckInterrupt()
  26. ) {
  27. // 如果是因为 interrupt 被唤醒, 返回打断状态为 true
  28. interrupted = true;
  29. }
  30. }
  31. } finally {
  32. if (failed)
  33. cancelAcquire(node);
  34. }
  35. }
  36. public final void acquire(int arg) {
  37. if (
  38. !tryAcquire(arg) &&
  39. acquireQueued(addWaiter(Node.EXCLUSIVE), arg)
  40. ) {
  41. // 如果打断状态为 true
  42. selfInterrupt();
  43. }
  44. }
  45. static void selfInterrupt() {
  46. // 重新产生一次中断
  47. Thread.currentThread().interrupt();
  48. }
  49. }

可打断模式

  1. static final class NonfairSync extends Sync {
  2. public final void acquireInterruptibly(int arg) throws InterruptedException {
  3. if (Thread.interrupted())
  4. throw new InterruptedException();
  5. // 如果没有获得到锁, 进入 ㈠
  6. if (!tryAcquire(arg))
  7. doAcquireInterruptibly(arg);
  8. }
  9. // ㈠ 可打断的获取锁流程
  10. private void doAcquireInterruptibly(int arg) throws InterruptedException {
  11. final Node node = addWaiter(Node.EXCLUSIVE);
  12. boolean failed = true;
  13. try {
  14. for (;;) {
  15. final Node p = node.predecessor();
  16. if (p == head && tryAcquire(arg)) {
  17. setHead(node);
  18. p.next = null; // help GC
  19. failed = false;
  20. return;
  21. }
  22. if (shouldParkAfterFailedAcquire(p, node) &&
  23. parkAndCheckInterrupt()) {
  24. // 在 park 过程中如果被 interrupt 会进入此
  25. // 这时候抛出异常, 而不会再次进入 for (;;)
  26. throw new InterruptedException();
  27. }
  28. }
  29. } finally {
  30. if (failed)
  31. cancelAcquire(node);
  32. }
  33. }
  34. }

4、 公平锁实现原理

  1. static final class FairSync extends Sync {
  2. private static final long serialVersionUID = -3000897897090466540L;
  3. final void lock() {
  4. acquire(1);
  5. }
  6. // AQS 继承过来的方法, 方便阅读, 放在此处
  7. public final void acquire(int arg) {
  8. if (
  9. !tryAcquire(arg) &&
  10. acquireQueued(addWaiter(Node.EXCLUSIVE), arg)
  11. ) {
  12. selfInterrupt();
  13. }
  14. }
  15. // 与非公平锁主要区别在于 tryAcquire 方法的实现
  16. protected final boolean tryAcquire(int acquires) {
  17. final Thread current = Thread.currentThread();
  18. int c = getState();
  19. if (c == 0) {
  20. // 先检查 AQS 队列中是否有前驱节点, 没有才去竞争
  21. if (!hasQueuedPredecessors() &&
  22. compareAndSetState(0, acquires)) {
  23. setExclusiveOwnerThread(current);
  24. return true;
  25. }
  26. }
  27. else if (current == getExclusiveOwnerThread()) {
  28. int nextc = c + acquires;
  29. if (nextc < 0)
  30. throw new Error("Maximum lock count exceeded");
  31. setState(nextc);
  32. return true;
  33. }
  34. return false;
  35. }
  36. // ㈠ AQS 继承过来的方法, 方便阅读, 放在此处
  37. public final boolean hasQueuedPredecessors() {
  38. Node t = tail;
  39. Node h = head;
  40. Node s;
  41. // h != t 时表示队列中有 Node
  42. return h != t &&
  43. (
  44. // (s = h.next) == null 表示队列中还有没有老二
  45. (s = h.next) == null ||
  46. // 或者队列中老二线程不是此线程
  47. s.thread != Thread.currentThread()
  48. );
  49. }
  50. }

5、 条件变量实现原理

每个条件变量其实就对应着一个等待队列,其实现类是 ConditionObject

await 流程

开始 Thread-0 持有锁,调用 await,进入 ConditionObject 的 addConditionWaiter 流程 创建新的 Node 状态为 -2(Node.CONDITION),关联 Thread-0,加入等待队列尾部
image.png
接下来进入 AQS 的 fullyRelease 流程,释放同步器上的锁
image.png
unpark AQS 队列中的下一个节点,竞争锁,假设没有其他竞争线程,那么 Thread-1 竞争成功
image.png
park 阻塞 Thread-0
image.png

signal 流程

假设 Thread-1 要来唤醒 Thread-0
image.png
进入 ConditionObject 的 doSignal 流程,取得等待队列中第一个 Node,即 Thread-0 所在 Node
image.png
执行 transferForSignal 流程,将该 Node 加入 AQS 队列尾部,将 Thread-0 的 waitStatus 改为 0,Thread-3 的 waitStatus 改为 -1
image.png
Thread-1 释放锁,进入 unlock 流程,略

源码

  1. public class ConditionObject implements Condition, java.io.Serializable {
  2. private static final long serialVersionUID = 1173984872572414699L;
  3. // 第一个等待节点
  4. private transient Node firstWaiter;
  5. // 最后一个等待节点
  6. private transient Node lastWaiter;
  7. public ConditionObject() { }
  8. // ㈠ 添加一个 Node 至等待队列
  9. private Node addConditionWaiter() {
  10. Node t = lastWaiter;
  11. // 所有已取消的 Node 从队列链表删除, 见 ㈡
  12. if (t != null && t.waitStatus != Node.CONDITION) {
  13. unlinkCancelledWaiters();
  14. t = lastWaiter;
  15. }
  16. // 创建一个关联当前线程的新 Node, 添加至队列尾部
  17. Node node = new Node(Thread.currentThread(), Node.CONDITION);
  18. if (t == null)
  19. firstWaiter = node;
  20. else
  21. t.nextWaiter = node;
  22. lastWaiter = node;
  23. return node;
  24. }
  25. // 唤醒 - 将没取消的第一个节点转移至 AQS 队列
  26. private void doSignal(Node first) {
  27. do {
  28. // 已经是尾节点了
  29. if ( (firstWaiter = first.nextWaiter) == null) {
  30. lastWaiter = null;
  31. }
  32. first.nextWaiter = null;
  33. } while (
  34. // 将等待队列中的 Node 转移至 AQS 队列, 不成功且还有节点则继续循环 ㈢
  35. !transferForSignal(first) &&
  36. // 队列还有节点
  37. (first = firstWaiter) != null
  38. );
  39. }
  40. // 外部类方法, 方便阅读, 放在此处
  41. // ㈢ 如果节点状态是取消, 返回 false 表示转移失败, 否则转移成功
  42. final boolean transferForSignal(Node node) {
  43. // 如果状态已经不是 Node.CONDITION, 说明被取消了
  44. if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
  45. return false;
  46. // 加入 AQS 队列尾部
  47. Node p = enq(node);
  48. int ws = p.waitStatus;
  49. if (
  50. // 上一个节点被取消
  51. ws > 0 ||
  52. // 上一个节点不能设置状态为 Node.SIGNAL
  53. !compareAndSetWaitStatus(p, ws, Node.SIGNAL)
  54. ) {
  55. // unpark 取消阻塞, 让线程重新同步状态
  56. LockSupport.unpark(node.thread);
  57. }
  58. return true;
  59. }
  60. // 全部唤醒 - 等待队列的所有节点转移至 AQS 队列
  61. private void doSignalAll(Node first) {
  62. lastWaiter = firstWaiter = null;
  63. do {
  64. Node next = first.nextWaiter;
  65. first.nextWaiter = null;
  66. transferForSignal(first);
  67. first = next;
  68. } while (first != null);
  69. }
  70. // ㈡
  71. private void unlinkCancelledWaiters() {
  72. // ...
  73. }
  74. // 唤醒 - 必须持有锁才能唤醒, 因此 doSignal 内无需考虑加锁
  75. public final void signal() {
  76. if (!isHeldExclusively())
  77. throw new IllegalMonitorStateException();
  78. Node first = firstWaiter;
  79. if (first != null)
  80. doSignal(first);
  81. }
  82. // 全部唤醒 - 必须持有锁才能唤醒, 因此 doSignalAll 内无需考虑加锁
  83. public final void signalAll() {
  84. if (!isHeldExclusively())
  85. throw new IllegalMonitorStateException();
  86. Node first = firstWaiter;
  87. if (first != null)
  88. doSignalAll(first);
  89. }
  90. // 不可打断等待 - 直到被唤醒
  91. public final void awaitUninterruptibly() {
  92. // 添加一个 Node 至等待队列, 见 ㈠
  93. Node node = addConditionWaiter();
  94. // 释放节点持有的锁, 见 ㈣
  95. int savedState = fullyRelease(node);
  96. boolean interrupted = false;
  97. // 如果该节点还没有转移至 AQS 队列, 阻塞
  98. while (!isOnSyncQueue(node)) {
  99. // park 阻塞
  100. LockSupport.park(this);
  101. // 如果被打断, 仅设置打断状态
  102. if (Thread.interrupted())
  103. interrupted = true;
  104. }
  105. // 唤醒后, 尝试竞争锁, 如果失败进入 AQS 队列
  106. if (acquireQueued(node, savedState) || interrupted)
  107. selfInterrupt();
  108. }
  109. // 外部类方法, 方便阅读, 放在此处
  110. // ㈣ 因为某线程可能重入,需要将 state 全部释放
  111. final int fullyRelease(Node node) {
  112. boolean failed = true;
  113. try {
  114. int savedState = getState();
  115. if (release(savedState)) {
  116. failed = false;
  117. return savedState;
  118. } else {
  119. throw new IllegalMonitorStateException();
  120. }
  121. } finally {
  122. if (failed)
  123. node.waitStatus = Node.CANCELLED;
  124. }
  125. }
  126. // 打断模式 - 在退出等待时重新设置打断状态
  127. private static final int REINTERRUPT = 1;
  128. // 打断模式 - 在退出等待时抛出异常
  129. private static final int THROW_IE = -1;
  130. // 判断打断模式
  131. private int checkInterruptWhileWaiting(Node node) {
  132. return Thread.interrupted() ?
  133. (transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) :
  134. 0;
  135. }
  136. // ㈤ 应用打断模式
  137. private void reportInterruptAfterWait(int interruptMode)
  138. throws InterruptedException {
  139. if (interruptMode == THROW_IE)
  140. throw new InterruptedException();
  141. else if (interruptMode == REINTERRUPT)
  142. selfInterrupt();
  143. }
  144. // 等待 - 直到被唤醒或打断
  145. public final void await() throws InterruptedException {
  146. if (Thread.interrupted()) {
  147. throw new InterruptedException();
  148. }
  149. // 添加一个 Node 至等待队列, 见 ㈠
  150. Node node = addConditionWaiter();
  151. // 释放节点持有的锁
  152. int savedState = fullyRelease(node);
  153. int interruptMode = 0;
  154. // 如果该节点还没有转移至 AQS 队列, 阻塞
  155. while (!isOnSyncQueue(node)) {
  156. // park 阻塞
  157. LockSupport.park(this);
  158. // 如果被打断, 退出等待队列
  159. if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
  160. break;
  161. }
  162. // 退出等待队列后, 还需要获得 AQS 队列的锁
  163. if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
  164. interruptMode = REINTERRUPT;
  165. // 所有已取消的 Node 从队列链表删除, 见 ㈡
  166. if (node.nextWaiter != null)
  167. unlinkCancelledWaiters();
  168. // 应用打断模式, 见 ㈤
  169. if (interruptMode != 0)
  170. reportInterruptAfterWait(interruptMode);
  171. }
  172. // 等待 - 直到被唤醒或打断或超时
  173. public final long awaitNanos(long nanosTimeout) throws InterruptedException {
  174. if (Thread.interrupted()) {
  175. throw new InterruptedException();
  176. }
  177. // 添加一个 Node 至等待队列, 见 ㈠
  178. Node node = addConditionWaiter();
  179. // 释放节点持有的锁
  180. int savedState = fullyRelease(node);
  181. // 获得最后期限
  182. final long deadline = System.nanoTime() + nanosTimeout;
  183. int interruptMode = 0;
  184. // 如果该节点还没有转移至 AQS 队列, 阻塞
  185. while (!isOnSyncQueue(node)) {
  186. // 已超时, 退出等待队列
  187. if (nanosTimeout <= 0L) {
  188. transferAfterCancelledWait(node);
  189. break;
  190. }
  191. // park 阻塞一定时间, spinForTimeoutThreshold 为 1000 ns
  192. if (nanosTimeout >= spinForTimeoutThreshold)
  193. LockSupport.parkNanos(this, nanosTimeout);
  194. // 如果被打断, 退出等待队列
  195. if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
  196. break;
  197. nanosTimeout = deadline - System.nanoTime();
  198. }
  199. // 退出等待队列后, 还需要获得 AQS 队列的锁
  200. if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
  201. interruptMode = REINTERRUPT;
  202. // 所有已取消的 Node 从队列链表删除, 见 ㈡
  203. if (node.nextWaiter != null)
  204. unlinkCancelledWaiters();
  205. // 应用打断模式, 见 ㈤
  206. if (interruptMode != 0)
  207. reportInterruptAfterWait(interruptMode);
  208. return deadline - System.nanoTime();
  209. }
  210. // 等待 - 直到被唤醒或打断或超时, 逻辑类似于 awaitNanos
  211. public final boolean awaitUntil(Date deadline) throws InterruptedException {
  212. // ...
  213. }
  214. // 等待 - 直到被唤醒或打断或超时, 逻辑类似于 awaitNanos
  215. public final boolean await(long time, TimeUnit unit) throws InterruptedException {
  216. // ...
  217. }
  218. // 工具方法 省略 ...
  219. }