2022年9月14日 作者 zeroheart

转载一篇文章,关于CountDownLatch和线程池的拒绝策略

原文:https://juejin.cn/post/7129116234804625421

先简单介绍下业务场景,针对用户批量下载的文件进行修改上传

未命名文件.png

为了提高执行的速度,所以在采用线程池去执行 下载-修改-上传 的操作,并在全部执行完之后统一提交保存文件地址到数据库,于是加入了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时候,记得加上超时时间,给一个兜底。