公平锁
非公平锁 都会调用acquire方法
public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); }
1 使用tryacquire获取锁 2 未获取到锁,则将当前线程添加到等到队列
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))原理剖析
- 线程A获取到锁,但是未释放
- 线程B尝试获取锁,但是锁未被释放,因此进入等待队列
- 线程C尝试获取锁,但是锁未被释放,因此进入等待队列
AbstractQueuedSynchronizer
final boolean acquireQueued(final Node node, int arg) { boolean failed = true; try { boolean interrupted = false; for (;;) { final Node p = node.predecessor(); if (p == head && tryAcquire(arg)) { setHead(node); p.next = null; // help GC failed = false; return interrupted; } if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) interrupted = true; } } finally { if (failed) cancelAcquire(node); } }
当前线程的前驱不是head节点(空节点,不存储线程相关信息),且获取锁失败(tryAcquire),则判断是否需要阻塞当前线程 shouldParkAfterFailedAcquire
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) { int ws = pred.waitStatus; if (ws == Node.SIGNAL) /* * This node has already set status asking a release * to signal it, so it can safely park. */ return true; if (ws > 0) { /* * Predecessor was cancelled. Skip over predecessors and * indicate retry. */ do { node.prev = pred = pred.prev; } while (pred.waitStatus > 0); pred.next = node; } else { /* * waitStatus must be 0 or PROPAGATE. Indicate that we * need a signal, but don't park yet. Caller will need to * retry to make sure it cannot acquire before parking. */ compareAndSetWaitStatus(pred, ws, Node.SIGNAL); } return false; }
判断当前线程是否需要被阻塞(加入等待队列)流程图 shouldParkAfterFailedAcquire