Java 利用JUC CountDownLatch 线程池Executors 实现多线程操作
业务场景:某个业务操作非常耗时,但又必须等这个操作结束后才能进行后续操作
importorg.springframework.util.CollectionUtils;
importjava.util.List;
importjava.util.concurrent.CountDownLatch;
importjava.util.concurrent.ExecutorService;
importjava.util.concurrent.Executors;
importjava.util.concurrent.TimeUnit;
importjava.util.function.Consumer;
importjava.util.stream.Collectors;
importjava.util.stream.Stream;
/**
* 多线程任务处理工具类
* gzh-JavaNice
*/
publicclassTaskDisposeUtils {
//并行线程数
publicstaticfinalintPOOL_SIZE;
static {
//判断核心线程数 如果机器的核心线程数大于5则用机器核心线程数
POOL_SIZE=Integer.max(Runtime.getRuntime().availableProcessors(), 5);
}
/**
* 并行处理,并等待结束
*
* @param taskList 任务列表
* @param consumer 消费者
* @param <T>
* @throws InterruptedException
*/
publicstatic<T>voiddispose(List<T>taskList, Consumer<T>consumer) throwsInterruptedException {
dispose(true, POOL_SIZE, taskList, consumer);
}
/**
* 并行处理,并等待结束
*
* @param moreThread 是否多线程执行
* @param poolSize 线程池大小
* @param taskList 任务列表
* @param consumer 消费者
* @param <T>
* @throws InterruptedException
*/
publicstatic<T>voiddispose(booleanmoreThread, intpoolSize, List<T>taskList, Consumer<T>consumer) throwsInterruptedException {
if (CollectionUtils.isEmpty(taskList)) {
return;
}
//如果是多线程且核心线程数大于一则进入方法
if (moreThread&&poolSize>1) {
poolSize=Math.min(poolSize, taskList.size());
ExecutorServiceexecutorService=null;
try {
//新建一个固定大小的线程池 核心线程数为poolSize
executorService=Executors.newFixedThreadPool(poolSize);
//juc工具类 用于让必须所有任务都处理完后才进行下一步
CountDownLatchcountDownLatch=newCountDownLatch(taskList.size());
for (Titem : taskList) {
executorService.execute(() -> {
try {
//消费任务
consumer.accept(item);
} finally {
//处理完后减一
countDownLatch.countDown();
}
});
}
//在此等待 当countDownLatch变成0后才继续进行下一步
countDownLatch.await();
} finally {
if (executorService!=null) {
executorService.shutdown();
}
}
} else {
for (Titem : taskList) {
consumer.accept(item);
}
}
}
publicstaticvoidmain(String[] args) throwsInterruptedException {
//生成1-10的10个数字,放在list中,相当于10个任务
List<Integer>list=Stream.iterate(1, a->a+1).limit(10).collect(Collectors.toList());
JSONObjectobject=newJSONObject();
object.put("name","sss");
//启动多线程处理list中的数据,每个任务休眠时间为list中的数值
// Consumer<Integer> c= item -> {
// try {
// long startTime = System.currentTimeMillis();
// object.put("s",item);
// TimeUnit.SECONDS.sleep(item);
// long endTime = System.currentTimeMillis();
// System.out.println(object.toJSONString());
// System.out.println(System.currentTimeMillis() + ",任务" + item + "执行完毕,耗时:" + (endTime - startTime));
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// };
TaskDisposeUtils.dispose(list, item-> {
try {
longstartTime=System.currentTimeMillis();
object.put("s",item);
TimeUnit.SECONDS.sleep(item);
longendTime=System.currentTimeMillis();
System.out.println(object.toJSONString());
System.out.println(System.currentTimeMillis() +",任务"+item+"执行完毕,耗时:"+ (endTime-startTime));
} catch (InterruptedExceptione) {
e.printStackTrace();
}
});
//上面所有任务处理完毕完毕之后,程序才能继续
System.out.println(list+"中的任务都处理完毕!");
}
}
执行结果
🖊️最后总结
🖲要熟练掌握技巧,一定多多坚持练习:骐骥一跃,不能十步;驽马十驾,功在不舍。