求助 CompletableFuture 怎么取消其任务 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
mengjisang
V2EX    Java

求助 CompletableFuture 怎么取消其任务

  •  
  •   mengjisang 2024-04-15 17:24:06 +08:00 2550 次点击
    这是一个创建于 610 天前的主题,其中的信息可能已经有所发展或是发生改变。

    查询到 cancel 方法其原型为

     /* ------------- Control and status methods -------------- */ /** * If not already completed, competes this CompletableFuture with * a {@link CancellationException}. Dependent CompletableFutures * that have not already completed will also complete * exceptionally, with a {@link CompletionException} caused by * this {@code CancellationException}. * * @param mayInterruptIfRunning this value has no effect in this * implementation because interrupts are not used to control * processing. * * @return {@code true} if this task is now cancelled */ public boolean cancel(boolean mayInterruptIfRunning) { boolean cancelled = (result == null) && internalComplete(new AltResult(new CancellationException())); postComplete(); return cancelled || isCancelled(); } 

    mayInterruptIfRunning 参数实际并没有被用到,取消操作实际是软取消,并不会直接从线程池中进行取消操作, 实际测试发现 cancel 确实有问题,没有按照想象中快速取消超时任务,最终会导致线程池阻塞,不知道该怎么办

    9 条回复    2024-04-16 17:03:09 +08:00
    BBCCBB
        1
    BBCCBB  
       2024-04-15 17:32:15 +08:00
    线程已经开始执行, 又没有可以被 interupt 的操作, 是取消不了的. 取消只是一个信号通知, 要代码里有响应才行.

    线程跑到一半, 也不能直接把线程 destory 了不是?
    mengjisang
        2
    mengjisang  
    OP
       2024-04-15 17:43:58 +08:00
    @BBCCBB 大概明白了,这个 cancel 方法,似乎就是设置了一下内部状态,然后抛出 CancellationException 异常
    xiaofan2
        3
    xiaofan2  
       2024-04-15 18:52:15 +08:00
    取消都是通知操作 无论是线程池还是其他的业务场景 真正要不要获取这种信号以及如何处理应该由业务逻辑处理 你看看 InterruptException
    inter12
        4
    inter12  
       2024-04-15 19:05:28 +08:00
    1.把线程放到一个上下文中
    2.在线程逻辑里面放置一个钩子
    3.触发这个钩子
    guyeu
        5
    guyeu  
       2024-04-15 20:56:04 +08:00   1
    你的目的是不要线程池阻塞?这里的阻塞不是一个很清晰的表述,假如它是指避免一个任务长期占用线程:
    1. 对于计算密集型任务,唯一实际可用的办法是在逻辑里去检查线程的内部状态然后按照业务去处理(早期版本可以用一个叫`Thread.stop`的方法来暴力停止,但这不是一个生产可用的选项);
    2. 对于 IO 密集型任务,合理的实现都会响应`interrupt`信号,因此`cancel`方法就足够了。

    实际上,更常见的需求是避免任务堆积导致内存压力,这种情况下:
    1. 限制阻塞队列的长度,并设计合理的拒绝策略;
    2. 解决资源瓶颈,缺 CPU 就加 CPU ,缺消费者就增加消费者节点。
    wolfie
        6
    wolfie  
       2024-04-15 21:42:33 +08:00
    interrupt 是多线程通信的一个标记,没开始的任务可以终止。
    建议贴出原始需求。
    vela
        7
    vela  
       2024-04-16 07:32:54 +08:00
    Java 之所以是比较安全的语言,就是这样设计的……你可以让一个线程「去死」,但是人家愿意不愿意死,甚至愿意不愿意理你,都是人家的自由。我见过太多开发者不正确的处理 InterruptedException 了。这样的代码如果你尝试 cancel(true),就坐等杯具了。
    Karte
        8
    Karte  
       2024-04-16 09:45:34 +08:00
    Interrupted 会告知线程当前是否被中断, 需要在 run() 方法中判断. 如果没有判断这个通知就是无效的, 线程依旧会执行. 还有如果收到了 interrupted 中断, 建议手动再次执行 `Thread.currentThread().interrupt();`, 这样可以让上层感知到线程被中断了.
    mengjisang
        9
    mengjisang  
    OP
       2024-04-16 17:03:09 +08:00
    结论就是,CompletableFuture 能中断那些没有被放入线程池执行的任务,已经执行的会抛出中断信号,但是线程内的任务何时退出则取决于任务执行情况和线程池的调度。

    因为,最后我用了 ReentrantLock 来保证每次只有一个线程去执行定时任务,只有一个线程占用线程池资源,另外如果要外部判断线程池的状态,则需要再启一个线程去定时轮询
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1581 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 23ms UTC 16:23 PVG 00:23 LAX 08:23 JFK 11:23
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86