并发编程(11)CountDownLatch

如果你的一个线程启动了多个线程来执行一些任务,此时你的这个线程需要同步阻塞等待那些线程都执行完毕了,才可以继续往下走,此时可以用CountDownLatch。CountDownLatch强调一个线程等多个线程完成某件事情。

await()方法

public final void acquireSharedInterruptibly(int arg)
        throws InterruptedException {
    if (Thread.interrupted())
        throw new InterruptedException();
    
    if (tryAcquireShared(arg) < 0)
        doAcquireSharedInterruptibly(arg);
}
private void doAcquireSharedInterruptibly(int arg) throws InterruptedException {
    //将当前线程放入AQS的等待队列中,入队去等待。
    final Node node = addWaiter(Node.SHARED);
    boolean failed = true;
    try {
        for (;;) {
            final Node p = node.predecessor();
            if (p == head) {
                //如果state!=0,那么r=-1。
                int r = tryAcquireShared(arg);
                if (r >= 0) {
                    setHeadAndPropagate(node, r);
                    p.next = null; // help GC
                    failed = false;
                    return;
                }
            }
            //通过park操作挂起阻塞,等待别人把它从队列里来唤醒。
            if (shouldParkAfterFailedAcquire(p, node) &&
                parkAndCheckInterrupt())
                throw new InterruptedException();
        }
    } finally {
        if (failed)
            cancelAcquire(node);
    }
}

countDown方法

public final boolean releaseShared(int arg) {
    //tryReleaseShared:基于CAS设置state的值
    if (tryReleaseShared(arg)) {
        doReleaseShared();
        return true;
    }
    return false;
}
protected boolean tryReleaseShared(int releases) {
    // Decrement count; signal when transition to zero
    for (;;) {
        int c = getState();
        //c == 0 直接返回,释放锁成功
        if (c == 0)
            return false;
        int nextc = c-1;
        //更新锁状态(state)
        if (compareAndSetState(c, nextc))
            return nextc == 0;
    }
}

代码示例:

public class CountDownLatchTest {
    private static CountDownLatch countDownLatch = new CountDownLatch(5);
    /**
     * Boss线程,等待员工到达开会
     */
    static class BossThread extends Thread{
        @Override
        public void run() {
            System.out.println("Boss在会议室等待,总共有" + countDownLatch.getCount() + "个人开会...");
            try {
                //Boss等待
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("所有人都已经到齐了,开会吧...");
        }
    }
    //员工到达会议室
    static class EmpleoyeeThread  extends Thread{
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + ",到达会议室....");
            //员工到达会议室 count - 1
            countDownLatch.countDown();
        }
    }
    public static void main(String[] args){
        //Boss线程启动
        new BossThread().start();

        for(int i = 0 ; i < countDownLatch.getCount() ; i++){
            new EmpleoyeeThread().start();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq40988670/article/details/86613533