java future 异常处理,java – 如何捕获CompletableFuture的whenCompleteAsync调用中抛出的RejectedExecutionException?...

按照示例代码我正在注入一个睡眠100毫秒的双音素作为一组完成未来的完成动作.我通过给出一个单独的executorService来使用whenCompleteAsync方法. executorService是一个ThreadPoolExecutor,核心池大小为5,最大大小为5,队列长度为1.

public class CompleteTest {

public static void main(String[] args) {

ExecutorService executorService = new ThreadPoolExecutor(5, 5, 10,

TimeUnit.SECONDS, new ArrayBlockingQueue<>(1));

ArrayList> list = new ArrayList<>();

for (int i = 0; i <100; i++) {

CompletableFuture stringCompletableFuture = new CompletableFuture<>();

stringCompletableFuture.whenCompleteAsync((e, a) -> {

System.out.println("Complete " + e);

try {

Thread.sleep(100);

} catch (InterruptedException e1) {e1.printStackTrace();}

}, executorService);

list.add(stringCompletableFuture);

}

for (int i = 0; i < list.size(); i++) {

list.get(i).complete(i + "");

}

}

}

当我运行代码时,即使我正在完成100个期货,也只会打印6个输出.这是5个核心线程和1个排队的线程.剩下的会怎么样?如果其他runnable由于队列已满而无法提交给执行程序服务,则不应该有异常.

产量

Complete 0

Complete 1

Complete 2

Complete 3

Complete 4

Complete 5

解决方法:

抛出异常,并且异常完成CompletableFuture,而不是您正在跟踪的任何一个.

您正在使用构造函数实例化和初始化ThreadPoolExecutor,该构造函数使用默认的RejectedExecutionHandler,它只是抛出异常.我们知道如果ExecutorService无法接受任务,则抛出RejectedExecutionException.那么任务添加到哪里以及抛出的异常在哪里?

就目前而言,所有链接都发生在完全同步时.当你调用它时,你将一个依赖项添加到接收者CompletableFuture,stringCompletableFuture.当stringCompletableFuture完成时(在这种情况下成功),它将创建一个新的CompletableFuture(它返回)并尝试在给定的ExecutorService上安排给定的BiConsumer.

由于ExecutorService的队列没有空格,因此它将调用RejectedExecutionHandler,它将抛出RejectedExecutionException.该异常在那时被捕获并且用于完成将返回的CompletableFuture.

换句话说,在for循环中,捕获whenCompleteAsync返回的CompletableFuture,存储它,并打印出它的状态.

ArrayList> list = new ArrayList<>();

ArrayList> dependents = new ArrayList<>();

for (int i = 0; i <100; i++) {

CompletableFuture stringCompletableFuture = new CompletableFuture<>();

CompletableFuture> thisWillHaveException = stringCompletableFuture.whenCompleteAsync((e, a) -> {

System.out.println("Complete " + e);

try {

Thread.sleep(100);

} catch (InterruptedException e1) {e1.printStackTrace();}

}, executorService);

dependents.add(thisWillHaveException);

list.add(stringCompletableFuture);

}

for (int i = 0; i < list.size(); i++) {

list.get(i).complete(i + "");

}

Thread.sleep(2000);

dependents.forEach(cf -> {

cf.whenComplete((r, e) -> {

if (e != null)

System.out.println(cf + " " + e.getMessage());

});

});

您会注意到它们是全部(除了之前成功打印的6个)与RejectedExecutionException异常完成.

...

java.util.concurrent.CompletableFuture@2d8e6db6[Completed exceptionally] java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.CompletableFuture$UniWhenComplete@3f91beef rejected from java.util.concurrent.ThreadPoolExecutor@4eec7777[Running, pool size = 5, active threads = 5, queued tasks = 1, completed tasks = 0]

java.util.concurrent.CompletableFuture@23ab930d[Completed exceptionally] java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.CompletableFuture$UniWhenComplete@1a6c5a9e rejected from java.util.concurrent.ThreadPoolExecutor@4eec7777[Running, pool size = 5, active threads = 5, queued tasks = 1, completed tasks = 0]

java.util.concurrent.CompletableFuture@4534b60d[Completed exceptionally] java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.CompletableFuture$UniWhenComplete@37bba400 rejected from java.util.concurrent.ThreadPoolExecutor@4eec7777[Running, pool size = 5, active threads = 5, queued tasks = 1, completed tasks = 0]

标签:java,java-8,future,executorservice,completable-future

来源: https://codeday.me/bug/20190608/1197700.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值