程序员

CountDownLatch使用

2019-03-08  本文已影响0人  Randolph555

CountDownLatch结合多线程可以控制并发,异步先行,并发阻塞,充分利用多核cpu,同时处理多项事情,底层实现是sync、volatile 来做线程可见性。


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * CountDownLatch  中文翻译 倒计时门闩(shuan)
 * CountDownLatch可以控制并发,异步先行,同步等待,充分利用多核cpu,同时处理多项事情,底层实现是sync、volatile 来做线程可见性
 * The synchronization state.
 * private volatile int state;
 *
 */
public class CountDownLatchTest {

    public static final Logger logger = LoggerFactory.getLogger(CountDownLatchTest.class);

    public static void main(String[] args) throws InterruptedException {


        /**
         * Constructs a {@code CountDownLatch} initialized with the given count.
         *
         * @param count the number of times {@link #countDown} must be invoked
         *        before threads can pass through {@link #await}
         * @throws IllegalArgumentException if {@code count} is negative
         */

        //初始化5个count数,也就是说有5把锁,为负数则抛出IllegalArgumentException
        final CountDownLatch countDownLatch = new CountDownLatch(5);


        /**
         * Creates a thread pool that reuses a fixed number of threads
         * operating off a shared unbounded queue.  At any point, at most
         * {@code nThreads} threads will be active processing tasks.
         * If additional tasks are submitted when all threads are active,
         * they will wait in the queue until a thread is available.
         * If any thread terminates due to a failure during execution
         * prior to shutdown, a new one will take its place if needed to
         * execute subsequent tasks.  The threads in the pool will exist
         * until it is explicitly {@link ExecutorService#shutdown shutdown}.
         *
         * @param nThreads the number of threads in the pool
         * @return the newly created thread pool
         * @throws IllegalArgumentException if {@code nThreads <= 0}
         */

        //创建一个固定5个线程数量的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(5);

        //模拟5次请求
        for (int i = 0; i < 5; i++) {
            //并发执行
            executorService.execute(() -> {
                logger.info(Thread.currentThread().getName() + "准备解锁");
                //开始解锁,每执行一次,解除一把锁
                countDownLatch.countDown();
                logger.info(Thread.currentThread().getName() + "已解锁");
            });
        }
        logger.info("等待解锁中...");
        //当锁的数量不为0时,一直在这里阻塞
        countDownLatch.await();

       logger.info("全部释放,任务执行完成,开始执行后续动作...");
        //关闭线程池
        executorService.shutdown();
    }
}

日志输出:


18:29:58.585 [main] INFO com.test.tenant.CountDownLatchTest - 等待解锁中...
18:29:58.584 [pool-1-thread-2] INFO com.test.tenant.CountDownLatchTest - pool-1-thread-2准备解锁
18:29:58.585 [pool-1-thread-1] INFO com.test.tenant.CountDownLatchTest - pool-1-thread-1准备解锁
18:29:58.588 [pool-1-thread-2] INFO com.test.tenant.CountDownLatchTest - pool-1-thread-2已解锁
18:29:58.585 [pool-1-thread-3] INFO com.test.tenant.CountDownLatchTest - pool-1-thread-3准备解锁
18:29:58.584 [pool-1-thread-5] INFO com.test.tenant.CountDownLatchTest - pool-1-thread-5准备解锁
18:29:58.588 [pool-1-thread-3] INFO com.test.tenant.CountDownLatchTest - pool-1-thread-3已解锁
18:29:58.588 [pool-1-thread-5] INFO com.test.tenant.CountDownLatchTest - pool-1-thread-5已解锁
18:29:58.588 [pool-1-thread-1] INFO com.test.tenant.CountDownLatchTest - pool-1-thread-1已解锁
18:29:58.584 [pool-1-thread-4] INFO com.test.tenant.CountDownLatchTest - pool-1-thread-4准备解锁
18:29:58.588 [pool-1-thread-4] INFO com.test.tenant.CountDownLatchTest - pool-1-thread-4已解锁
18:29:58.588 [main] INFO com.test.tenant.CountDownLatchTest - 全部释放,任务执行完成,开始执行后续动作...

Process finished with exit code 0
上一篇下一篇

猜你喜欢

热点阅读