从lock方法开始

1.lock

  1. static final class NonfairSync extends Sync {
  2. private static final long serialVersionUID = 7316153563782823691L;
  3. final void lock() {
  4. if (compareAndSetState(0, 1))
  5. setExclusiveOwnerThread(Thread.currentThread());
  6. else
  7. acquire(1);
  8. }
  9. protected final boolean tryAcquire(int acquires) {
  10. return nonfairTryAcquire(acquires);
  11. }
  12. }
  1. static final class FairSync extends Sync {
  2. private static final long serialVersionUID = -3000897897090466540L;
  3. final void lock() {
  4. acquire(1);
  5. }
  6. protected final boolean tryAcquire(int acquires) {
  7. final Thread current = Thread.currentThread();
  8. int c = getState();
  9. if (c == 0) {
  10. if (!hasQueuedPredecessors() &&
  11. compareAndSetState(0, acquires)) {
  12. setExclusiveOwnerThread(current);
  13. return true;
  14. }
  15. }
  16. else if (current == getExclusiveOwnerThread()) {
  17. int nextc = c + acquires;
  18. if (nextc < 0)
  19. throw new Error("Maximum lock count exceeded");
  20. setState(nextc);
  21. return true;
  22. }
  23. return false;
  24. }
  25. }

2.AbstractQueuedSynchronizer.acquire()

  1. public final void acquire(int arg) {
  2. if (!tryAcquire(arg) &&
  3. acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
  4. selfInterrupt();
  5. }

3.AbstractQueuedSynchronizer.tryAcquire() => nonfairTryAcquire()

  1. final boolean nonfairTryAcquire(int acquires) {
  2. final Thread current = Thread.currentThread();
  3. int c = getState();
  4. if (c == 0) {
  5. if (compareAndSetState(0, acquires)) {
  6. setExclusiveOwnerThread(current);
  7. return true;
  8. }
  9. }
  10. else if (current == getExclusiveOwnerThread()) {
  11. int nextc = c + acquires;
  12. if (nextc < 0) // overflow
  13. throw new Error("Maximum lock count exceeded");
  14. setState(nextc);
  15. return true;
  16. }
  17. return false;
  18. }

3.1 如果t2加锁成功 setExclusiveOwnerThread()

  1. protected final void setExclusiveOwnerThread(Thread thread) {
  2. exclusiveOwnerThread = thread;
  3. }

4. t2加锁失败 先addWaiter()

  1. private Node addWaiter(Node mode) {
  2. Node node = new Node(Thread.currentThread(), mode);
  3. // Try the fast path of enq; backup to full enq on failure
  4. Node pred = tail;
  5. if (pred != null) {
  6. node.prev = pred;
  7. if (compareAndSetTail(pred, node)) {
  8. pred.next = node;
  9. return node;
  10. }
  11. }
  12. enq(node);
  13. return node;
  14. }
  1. private Node enq(final Node node) {
  2. for (;;) {
  3. Node t = tail;
  4. if (t == null) { // Must initialize
  5. // 初始化 如果头结点为空,创建一个空的Node
  6. if (compareAndSetHead(new Node()))
  7. tail = head;
  8. } else {
  9. // 将node加入队尾(双向链表)
  10. node.prev = t;
  11. if (compareAndSetTail(t, node)) {
  12. t.next = node;
  13. return t;
  14. }
  15. }
  16. }
  17. }

5.再acquireQueued()

  1. final boolean acquireQueued(final Node node, int arg) {
  2. boolean failed = true;
  3. try {
  4. //interrupted 这个值用来防止打断
  5. boolean interrupted = false;
  6. for (;;) {
  7. final Node p = node.predecessor();
  8. //判断前一个节点是不是头结点,也就是初始化的那个空节点,如果是,就表示队列前面没有人排队,自己可以抢锁。
  9. if (p == head && tryAcquire(arg)) {
  10. setHead(node);
  11. p.next = null; // help GC
  12. failed = false;
  13. return interrupted;
  14. }
  15. //前面有人,就需要排队了
  16. // shouldParkAfterFailedAcquire 判断加锁失败之后是否需要去睡眠
  17. if (shouldParkAfterFailedAcquire(p, node) &&
  18. parkAndCheckInterrupt())
  19. interrupted = true;
  20. }
  21. } finally {
  22. if (failed)
  23. cancelAcquire(node);
  24. }
  25. }

5.1 shouldParkAfterFailedAcquire 告诉前一个节点解锁的时候把自己叫醒

  1. private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
  2. int ws = pred.waitStatus;
  3. // 判断上一个节点是不是需要唤醒别人的节点
  4. if (ws == Node.SIGNAL)
  5. /*
  6. * This node has already set status asking a release
  7. * to signal it, so it can safely park.
  8. */
  9. //如果上一个节点已经设置为-1,自己就直接去睡眠
  10. return true;
  11. if (ws > 0) {
  12. /*
  13. * Predecessor was cancelled. Skip over predecessors and
  14. * indicate retry.
  15. */
  16. do {
  17. node.prev = pred = pred.prev;
  18. } while (pred.waitStatus > 0);
  19. pred.next = node;
  20. } else {
  21. /*
  22. * waitStatus must be 0 or PROPAGATE. Indicate that we
  23. * need a signal, but don't park yet. Caller will need to
  24. * retry to make sure it cannot acquire before parking.
  25. */
  26. // 如果上一个节点还没有设置-1,就把它改成-1
  27. compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
  28. }
  29. return false;
  30. }