亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

從 CompletableFuture 調用 ExecutorService.shutdownNow

從 CompletableFuture 調用 ExecutorService.shutdownNow

狐的傳說 2021-08-04 17:20:41
當已經運行的任務之一引發異常時,我需要取消所有計劃但尚未運行的 CompletableFuture 任務。嘗試了以下示例,但大多數情況下 main 方法不會退出(可能是由于某種類型的死鎖)。public static void main(String[] args) {    ExecutorService executionService = Executors.newFixedThreadPool(5);    Set< CompletableFuture<?> > tasks = new HashSet<>();    for (int i = 0; i < 1000; i++) {        final int id = i;        CompletableFuture<?> c = CompletableFuture        .runAsync( () -> {            System.out.println("Running: " + id);             if ( id == 400 ) throw new RuntimeException("Exception from: " + id);        }, executionService )        .whenComplete( (v, ex) -> {             if ( ex != null ) {                System.out.println("Shutting down.");                executionService.shutdownNow();                System.out.println("shutdown.");            }        } );        tasks.add(c);    }    try{         CompletableFuture.allOf( tasks.stream().toArray(CompletableFuture[]::new) ).join();     }catch(Exception e) {         System.out.println("Got async exception: " + e);     }finally {         System.out.println("DONE");     }        }最后的打印輸出是這樣的:Running: 402Running: 400Running: 408Running: 407Running: 406Running: 405Running: 411Shutting down.Running: 410Running: 409Running: 413Running: 412shutdown.嘗試shutdownNow在單獨的線程上運行方法,但在大多數情況下,它仍然會出現相同的死鎖。知道什么可能導致這種僵局嗎?您認為在CompletableFuture拋出異常時取消所有已安排但尚未運行的s的最佳方法是什么?正在考慮迭代tasks并調用cancel每個CompletableFuture. 但我不喜歡這個的是CancellationException從join.
查看完整描述

2 回答

?
藍山帝景

TA貢獻1843條經驗 獲得超7個贊

另一個僅依賴的解決方案CompletableFuture是使用“取消者”未來,這將導致所有未完成的任務在完成時被取消:


Set<CompletableFuture<?>> tasks = ConcurrentHashMap.newKeySet();

CompletableFuture<Void> canceller = new CompletableFuture<>();


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

    if (canceller.isDone()) {

        System.out.println("Canceller invoked, not creating other futures.");

        break;

    }

    //LockSupport.parkNanos(10);

    final int id = i;

    CompletableFuture<?> c = CompletableFuture

            .runAsync(() -> {

                //LockSupport.parkNanos(1000);

                System.out.println("Running: " + id);

                if(id == 400) throw new RuntimeException("Exception from: " + id);

            }, executionService);

    c.whenComplete((v, ex) -> {

        if(ex != null) {

            canceller.complete(null);

        }

    });

    tasks.add(c);

}

canceller.thenRun(() -> {

    System.out.println("Cancelling all tasks.");

    tasks.forEach(t -> t.cancel(false));

    System.out.println("Finished cancelling tasks.");

});


查看完整回答
反對 回復 2021-08-04
  • 2 回答
  • 0 關注
  • 226 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號