CountDownLatch
1. CountDownLatch
- 倒计时锁;某个线程x当倒计时为0的时候才执行;倒计时其实就是一个int类型的变量,在初始化CountDownLatch的时候会给他一个初始值;在多线程工作的时候,使用await()阻塞线程,通过countDown()方法来对计数器-1;当等于0的时候线程则会解除阻塞运行。
基本语法
//初始化对象,给一个初始值
CountDownLatch latch = new CountDownLatch(3);
//x线程 调用await阻塞 等待计数器为0的时候才会解除阻塞
latch.await();
//其他线程调用countDown();对计数器-1
latch.countDown();
2. 代码示例
2.1 单机版
package org.example.CountDownLatch;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@Slf4j
public class CountDownLatchTest {
static int count = 3;
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(count);
for (int i = 0; i < count; i++) {
int time = i;
new Thread(() -> {
log.info("{} start...",Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
log.info("{} end...,count[{}]", Thread.currentThread().getName(), latch.getCount());
}, "t" + i).start();
}
log.info("main await start");
latch.await();
log.info("main await end");
}
}
2.2 配合线程池ExecutorService
package org.example.CountDownLatch;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
@Slf4j
public class CountDownLatchTest2 {
public static void main(String[] args){
AtomicInteger result1 = new AtomicInteger();
AtomicInteger result2 = new AtomicInteger();
AtomicInteger result3 = new AtomicInteger();
AtomicInteger finalResult = new AtomicInteger();
//线程池里面创建4个线程,其中前3个用于计算,第四个用于汇总前3个线程的计算结果
AtomicInteger i= new AtomicInteger();
ExecutorService executorService = Executors.newFixedThreadPool(4,
(fisher)-> new Thread(fisher,"t"+i.incrementAndGet()));
//前3个线程先执行
CountDownLatch latch = new CountDownLatch(3);
executorService.submit(()->{
log.debug("t1 thread start");
try {
TimeUnit.SECONDS.sleep(1);
result1.set(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
log.debug("t1 thread end;count[{}]", latch.getCount());
});
executorService.submit(()->{
log.debug("t2 thread start");
try {
TimeUnit.SECONDS.sleep(2);
result2.set(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
log.debug("t2 thread end;count[{}]", latch.getCount());
});
executorService.submit(()->{
log.debug("t3 thread start");
try {
TimeUnit.SECONDS.sleep(3);
result3.set(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
log.debug("t3 thread end;count[{}]", latch.getCount());
});
//汇总计算结果
executorService.submit(()->{
log.debug("t4 watiing");
try {
latch.await();
finalResult.set(result1.get() + result2.get() + result3.get());
} catch (InterruptedException e) {
e.printStackTrace();
}
log.debug("t4 wait end...");
log.debug("finalResult=" + finalResult);
});
executorService.shutdown();
}
}