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
网友评论