如何使用java.util.concurrent.ExecutorService
为并行运行的每个命令创建超时?
我的代码如下:
例如,在下面的代码中,我需要obj1
最多运行1分钟,obj2
运行2分钟,其他运行5分钟。
ExecutorService exService;
exService = Executors.newCachedThreadPool();
exService.execute(obj1);
exService.execute(obj2);
exService.execute(obj3);
exService.execute(obj4);
exService.shutdown();
boolean finshed = exService.awaitTermination(5, TimeUnit.MINUTES);
if (finshed) {
//Doing something
}
编辑:
不幸的是,obj1
-obj4
类正在使用WebHarvest抓取一些网页,该类使用jakarta HttpClient来读取网页,而HttpClient(WebHarvest-本身)在整个页面读取和/或抓取作业上都没有任何超时功能
这是我的一项耗时的任务,我曾想过在超时后杀死ExecutorService线程来处理这个问题。
通常,没有可靠的方法可以让单独的线程退出。特别是,在任务外部超时后,没有可靠的方法来中断和停止任务。你需要做的是让任务自己负责在时间用完后停止。根据他们所做的,你可能能够将这种行为抽象成一个超类,比如:
public abstract class TimeoutRunnable implements Runnable {
private final long timeLimitMillis;
private long startTimeMillis;
public TimeoutRunnable(long timeLimitMillis) {
this.timeLimitMillis = timeLimitMillis;
}
public final void run() {
startTimeMillis = System.currentTimeMillis();
while (System.currentTimeMillis() - startTimeMillis < timeLimitMillis) {
runIteration();
}
}
protected abstract void runIteration();
}
然后在子类覆盖中,runIteration()
并执行任务的单个"步骤"。
终止任务的唯一合理可靠的方法是在一个单独的进程中运行它,并在超时时终止该进程。对不支持超时的库使用任何其他方法最多都可能出错。
从我的角度来看,我认为这种东西需要比普通Java标准类更强大的基础,这就是为什么我建议使用任何调度器基础设施(Quartz或任何其他项目),它可能会为您提供句柄(作业标识符)来杀死耗时的任务。
你可能有这样的东西:
Main Thread启动Quartz Scheduler,接收来自不同作业的订阅说:作业1,作业2和TimeCheckerJob
TimeCheckerJob将是一份永远的工作,通知任何新工作,并检查每个新工作的生存时间。。。在这个作业中,您必须处理每个作业的开始时间,注意操作系统时钟,不要试图设置太严格的约束(纳秒纯属虚构)。
HTH我的2美分Jerome