countDownLatch的基本用法
public static void main(String[] args) {
int count = 5;
// 给定一个总数为5的调用次数
CountDownLatch latch = new CountDownLatch(count);
try {
for (int i = 0; i < count; i++) {
// 每执行一次,就从5里面减掉1
latch.countDown();
}
System.out.println("count= " + latch.getCount());
// 只有count等于0的时候,才会执行该方法,如果方法没有执行,多线程会一直阻塞
latch.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
RCountDownLatch基本用法
@Autowired
private RedissonClient redissonClient;
public void exec() {
int count = 5;
try {
RCountDownLatch downLatch = redissonClient.getCountDownLatch("随便写个字符串");
downLatch.trySetCount(count);
// 任务个数 - 1, 直至为0时唤醒await()
downLatch.countDown();
downLatch.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
线程池基本使用
CountDownLatch和ThreadPoolExecutor搭配使用
public static void main(String[] args) {
// 模拟从数据库查出了一堆数据
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 100; i++) {
list.add(i);
}
// 初始化线程池, 参数一定要一定要一定要调好
int cpus = Runtime.getRuntime().availableProcessors();
cpus = cpus < 16 ? 32 : cpus * 2;
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(cpus, cpus * 2,
4, TimeUnit.SECONDS, new LinkedBlockingDeque(), new ThreadPoolExecutor.AbortPolicy());
// 记录单个任务的执行次数
CountDownLatch countDownLatch = new CountDownLatch(list.size());
// 用到了hutool工具类,对大list进行切片,替换成小list,避免数据量太大,在对数据库进行批量操作时造成压力
List<List<Integer>> listOfSubLists = CollUtil.split(list, 10);
// 用foreach循环
listOfSubLists.forEach(x -> {
threadPool.execute(new Runnable() {
@Override
public void run() {
x.forEach(y -> {
// y代表集合中的一个最小对象,可以对该对象进行业务操作,比如入库、数值计算等
System.out.println("当前对象是:" + y);
// 任务个数 - 1, 直至为0时唤醒await()
countDownLatch.countDown();
});
}
});
});
try {
// 让当前线程处于阻塞状态,直到锁存器计数为零
countDownLatch.await();
} catch (Exception e) {
log.error(e.getMessage());
} finally {
//关闭线程池
threadPool.shutdown();
}
}