目标:运用CountDownLatch与Callable进行简单的计数
CountDownLatch
- 与CyclicBarrier相似,只是它只实现了一次任务拆分与整合,用来协调多个线程之间的同步。
- new CountDownLatch(int val):初始化时,需要设置信号值。
- countDown():每一次进行countDown都会是信号值-1。
- await():只有当信号值为0时,才会停止阻塞。
Callable
- 有返回值的线程运算体。与Runnable类似
- 需要利用FutureTask接收返回值。与Thread类似
代码实现:
package com.miracle.study.concurrent;
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.*;
/**
* @author Miracle
* @date 2021/4/14 18:03
*/
public class CountDownLatchTest {
static class Calculate implements Callable<Integer>{
/**
* 外部引入CountDownLatch
*/
private CountDownLatch countDownLatch;
private static final Random random = new Random();
public Calculate(CountDownLatch countDownLatch){
this.countDownLatch = countDownLatch;
}
@Override
public Integer call() throws Exception {
Thread.sleep(1000);
int val = random.nextInt(100);
// 进行计数减一
countDownLatch.countDown();
return val;
}
}
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(6);
var futureList = new ArrayList<FutureTask<Integer>>();
long count = countDownLatch.getCount();
// 循环添加5个计随机数任务
for (int i = 0; i < count; i++){
// 创建任务
FutureTask<Integer> futureTask = new FutureTask<>(new Calculate(countDownLatch));
// 执行任务
futureTask.run();
// 添加任务到队列中,方便后续进行数据输出
futureList.add(futureTask);
}
// 等待计数值为零时,才执行后面的代码
countDownLatch.await();
// 循环输出所有的值
futureList.stream().forEach(val -> {
try {
System.out.println(val.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
}
}