CountDownLatch
这个类大家可以学习学习,里面用了一个clh的自旋锁模式
大家可以看看关于自旋锁的介绍,他是一个公平锁。避免饥饿模式
https://www.jianshu.com/p/5ad8539e25c3
具体的代码可以看下node这个类,实现了自旋锁模式
贴下一些代码片段
abstractqueuedsynchronizer
doReleaseShared
Node 自旋锁 CLH locks
上锁
doAcquireSharedInterruptibly
node await
sync.acquireSharedInterruptibly(1);
doAcquireSharedInterruptibly(arg); parkAndCheckInterrupt 锁住当前线程
如果解锁 释放下个node 线程
unparkSuccessor
doReleaseShared 解锁
if (ws == Node.SIGNAL) {
if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
continue; // loop to recheck cases
unparkSuccessor(h);
解锁下一个
Node s = node.next;
if (s == null || s.waitStatus > 0) {
s = null;
for (Node t = tail; t != null && t != node; t = t.prev)
if (t.waitStatus <= 0)
s = t;
}
if (s != null)
LockSupport.unpark(s.thread);
下一个受到提醒
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
throw new InterruptedException();
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);
}