CountDownLatch結(jié)合多線(xiàn)程可以控制并發(fā),異步先行炸庞,并發(fā)阻塞,充分利用多核cpu荚斯,同時(shí)處理多項(xiàng)事情埠居,底層實(shí)現(xiàn)是sync、volatile 來(lái)做線(xiàn)程可見(jiàn)性事期。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* CountDownLatch 中文翻譯 倒計(jì)時(shí)門(mén)閂(shuan)
* CountDownLatch可以控制并發(fā)拐格,異步先行,同步等待刑赶,充分利用多核cpu,同時(shí)處理多項(xiàng)事情懂衩,底層實(shí)現(xiàn)是sync撞叨、volatile 來(lái)做線(xiàn)程可見(jiàn)性
* 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個(gè)count數(shù),也就是說(shuō)有5把鎖,為負(fù)數(shù)則拋出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}
*/
//創(chuàng)建一個(gè)固定5個(gè)線(xiàn)程數(shù)量的線(xiàn)程池
ExecutorService executorService = Executors.newFixedThreadPool(5);
//模擬5次請(qǐng)求
for (int i = 0; i < 5; i++) {
//并發(fā)執(zhí)行
executorService.execute(() -> {
logger.info(Thread.currentThread().getName() + "準(zhǔn)備解鎖");
//開(kāi)始解鎖浊洞,每執(zhí)行一次牵敷,解除一把鎖
countDownLatch.countDown();
logger.info(Thread.currentThread().getName() + "已解鎖");
});
}
logger.info("等待解鎖中...");
//當(dāng)鎖的數(shù)量不為0時(shí),一直在這里阻塞
countDownLatch.await();
logger.info("全部釋放法希,任務(wù)執(zhí)行完成,開(kāi)始執(zhí)行后續(xù)動(dòng)作...");
//關(guān)閉線(xiàn)程池
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準(zhǔn)備解鎖
18:29:58.585 [pool-1-thread-1] INFO com.test.tenant.CountDownLatchTest - pool-1-thread-1準(zhǔn)備解鎖
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準(zhǔn)備解鎖
18:29:58.584 [pool-1-thread-5] INFO com.test.tenant.CountDownLatchTest - pool-1-thread-5準(zhǔn)備解鎖
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準(zhǔn)備解鎖
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 - 全部釋放枷餐,任務(wù)執(zhí)行完成,開(kāi)始執(zhí)行后續(xù)動(dòng)作...
Process finished with exit code 0