ligx
V2EX  ›  Java

如何控制 java 线程池中任务的执行时间?

  •  
  •   ligx · Aug 25, 2015 · 7428 views
    This topic created in 3941 days ago, the information mentioned may be changed or developed.

    使用 ThreadPoolExedcutor 自定义线程池时,如何控制线程池中任务的执行时间?例如,当任务执行时间超过 1 分钟就取消该线程。(ps:除 Future 外)

    7 replies    2015-08-27 02:39:22 +08:00
    aisk
        2
    aisk  
       Aug 25, 2015
    再启一个线程来监控?
    SoloCompany
        4
    SoloCompany  
       Aug 26, 2015
    你的需求不明

    如果你想在超时的时候杀死一个执行中的线程,就要用到 Thread.stop, 这是 deprecated 的方法,不仅仅是不建议使用,而是不能使用, 因为强行终止一个线程会导致锁无法释放

    正确的做法是监控一个执行的线程,在超时时发送 interrup 信号来尝试终止线程,线程能正常终止(得到 InterruptedException ) 的前提是,你的线程是处于阻塞状态(比如, IO 阻塞,或在 wait 某个锁释放),而不是一直在执行耗时的代码(比如死循环了),后者如果要正常终结,你必须自己设计状态机,在耗时操作的地方插入检查状态机代码来终止
    MOsky
        5
    MOsky  
       Aug 26, 2015
    如楼上所说的情况。如果楼主你一定有这种需求,那么所有在线程池中运行的代码都满足如下两个条件,你就可以做到“安全”地中断一个任务了。

    1. 调用声明抛出 InterruptedException 的方法(当然包括 wait 方法)。不可以吃掉,应该优雅地中断当前任务。

    2. 遇到循环结构,每次都调用 Thread.interrupted () 检查,如果返回 true ,则中断当前循环,并优雅地中断当前任务。

    所以。如果你的线程池是设计来运行特定代码,而且这些代码一定会出现人力不可控因素导致的超时,那么你在设计这些代码时只需要做到以上两点即可。

    如果你的线程池可以用来执行任意代码,那就麻烦了。因为这些代码不一定满足以上两个条件。
    iluhcm
        6
    iluhcm  
       Aug 26, 2015
    @SoloCompany
    你的这个做法针对的是老的线程执行机制吧.

    Concurrent 包里边不是可以用 ExecutorService.shutdownNow ()来关闭 Task 么?
    SoloCompany
        7
    SoloCompany  
       Aug 27, 2015
    @iluhcm shutdownNow 就是设置状态机和发送 interrup 给各个还在活动的 worker 线程来实现终结啊,是否能终结成功还是得依赖 Task 的实现
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5971 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 80ms · UTC 02:30 · PVG 10:30 · LAX 19:30 · JFK 22:30
    ♥ Do have faith in what you're doing.