2022年9月14日
转载一篇文章,关于CountDownLatch和线程池的拒绝策略
原文:https://juejin.cn/post/7129116234804625421
先简单介绍下业务场景,针对用户批量下载的文件进行修改上传
为了提高执行的速度,所以在采用线程池去执行 下载-修改-上传 的操作,并在全部执行完之后统一提交保存文件地址到数据库,于是加入了CountDownLatch来进行控制。
具体实现
根据服务本身情况,自定义一个线程池
public static ExecutorService testExtcutor() {
return new ThreadPoolExecutor(
2,
2,
0L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(1));
}
复制代码
模拟执行
一开始我个人感觉没有什么问题,反正finally都能够做减一的操作,到最后调用await方法,进行主线程任务
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@300ffa5d rejected from java.util.concurrent.ThreadPoolExecutor@1f17ae12[Running, pool size = 2, active threads = 2, queued tasks = 1, completed tasks = 0]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
at Thread.executor.executorTestBlock.main(executorTestBlock.java:28)
原文说的问题就是在线程池中做任务,使用countdownLatch做合并提交,但是线程池走到了拒绝策略,导致countDown方法无法正常执行的问题,采取的是修改拒绝策略,使用当前线程处理的方式来执行的。也可以只用completableFuture来处理。
另一个例子:讲的也是拒绝策略的事情
https://juejin.cn/post/7186512174779465765
就是自定义拒绝策略的时候,要注意抛出异常、发送通知等处理,不要让异常被吃掉,可能会导致其他的问题。另外future.get时候,记得加上超时时间,给一个兜底。