对于这个问题,不清楚你想用超时做什么。在这里,我向您展示了实现轻量级超时的两个选项:受监控的与受控的。
监控超时
对于全局计时器,您可以使用 JDK 中的 Timer 工具:
public TimeoutTask implements TimerTask {
List<MonitorableObject> objects;
public TimeoutTask(List<MonitorableObject> objects) {
// make sure you can share this collection concurrently,
// e.g. copyonwritearraylist
this.objects = objects;
}
public void run() {
// objects -> filter(isTimeOut(currentTime)) -> do something
}
}
Timer timer = new Timer();
timer.schedule(new TimeoutTask(myObjectList), 0,60*1000); // repeat each 60secs
使用ScheduledExecutorService 可以进行类似的构造:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
// Note that I can use here TimeoutTask b/c TimerTask is a Runnable -
// this is just for the example. You'd better implement a plain runnable.
scheduler.schedule(new TimeoutTask(myObjectList), 60, TimeUnit.SECONDS);
我更喜欢ScheduledExecutorService 上面的Timer 设施,因为SchedulerExecutor 可以容纳一个线程池。此外,底层线程池可用于调用scheduledExecutorService.execute(...) 以立即并发执行(未调度)的其他操作,使其成为通用执行器工具,而不是专用计时器功能。
在这两种情况下,您都需要特别注意安全地从您正在监控的对象中获取超时值。通常,您将在对象中使用同步方法来询问它的超时状态。
强制超时
ExecutorService 为您提供了一个 API,可以在给定的超时时间内执行一组任务。例如
List<Callable<?>> myTasks = ...;
// populate myTasks with Callable`s that wrap your intended execution
ExecutorService executorService = ... ;
List<Future<?>> results = executorService.invokeAll(myTasks, 60, TimeUnit.SECONDS);
这个方法返回后,你可以在给定的时间内询问每个Future是否成功。