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

2015-08-25 13:39:36 +08:00
 ligx

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

6513 次点击
所在节点    Java
7 条回复
broadliyn
2015-08-25 14:21:22 +08:00
aisk
2015-08-25 15:16:42 +08:00
再启一个线程来监控?
xiaoyukid
2015-08-25 15:41:16 +08:00
SoloCompany
2015-08-26 09:06:25 +08:00
你的需求不明

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

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

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

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

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

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

Concurrent 包里边不是可以用 ExecutorService.shutdownNow ()来关闭 Task 么?
SoloCompany
2015-08-27 02:39:22 +08:00
@iluhcm shutdownNow 就是设置状态机和发送 interrup 给各个还在活动的 worker 线程来实现终结啊,是否能终结成功还是得依赖 Task 的实现

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/215827

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX