V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ligx
V2EX  ›  Java

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

  •  
  •   ligx · 2015-08-25 13:39:36 +08:00 · 6632 次点击
    这是一个创建于 3369 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    7 条回复    2015-08-27 02:39:22 +08:00
    aisk
        2
    aisk  
       2015-08-25 15:16:42 +08:00
    再启一个线程来监控?
    SoloCompany
        4
    SoloCompany  
       2015-08-26 09:06:25 +08:00
    你的需求不明

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

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

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

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

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

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

    Concurrent 包里边不是可以用 ExecutorService.shutdownNow ()来关闭 Task 么?
    SoloCompany
        7
    SoloCompany  
       2015-08-27 02:39:22 +08:00
    @iluhcm shutdownNow 就是设置状态机和发送 interrup 给各个还在活动的 worker 线程来实现终结啊,是否能终结成功还是得依赖 Task 的实现
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1027 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 20:54 · PVG 04:54 · LAX 12:54 · JFK 15:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.