public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(3); for (int i = 0; i < 3; i++) { new Thread(()->{ countDownLatch.countDown(); }).start(); } System.out.println("阻塞main线程"); countDownLatch.await(); System.out.println("main线程放行"); }前置知识
AQSCAS 构造器
1.初始化内部sync属性。
2.设置AQS state属性
public CountDownLatch(int count) { if (count < 0) throw new IllegalArgumentException("count < 0"); this.sync = new Sync(count); } private static final class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = 4982264981922014374L; Sync(int count) { setState(count); } int getCount() { return getState(); } protected int tryAcquireShared(int acquires) { return (getState() == 0) ? 1 : -1; } protected boolean tryReleaseShared(int releases) { // Decrement count; signal when transition to zero for (;;) { int c = getState(); if (c == 0) return false; int nextc = c-1; if (compareAndSetState(c, nextc)) return nextc == 0; } } }怎么阻塞当前线程的
countDownLatch.await(); public final void acquireSharedInterruptibly(int arg) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); //判断当前state (getState() == 0) ? 1 : -1; //!=0 表示 count数量的线程内有走完 if (tryAcquireShared(arg) < 0) doAcquireSharedInterruptibly(arg); } // private void doAcquireSharedInterruptibly(int arg) 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; } } //修改node等待状态, LockSupport.park(this);阻塞当前线程 if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) throw new InterruptedException(); } } finally { if (failed) cancelAcquire(node); } }怎么唤醒被阻塞线程
countDownLatch.countDown(); public final boolean releaseShared(int arg) { //state-1, return state == 0; if (tryReleaseShared(arg)) { //state == 0 唤醒队列中阻塞线程 doReleaseShared(); return true; } return false; }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)