有n
其执行一些操作的对象。 执行操作后,时间戳将被更新。 现在我想实现一个超时线程从而验证如果时间戳比例如在60秒钟之前的较早。
我的第一个解决办法是做与线程(while循环+睡眠),它正在与包括最后的时间戳的所有对象的列表。 现在我有有在线程需要59秒加上睡眠时间来决定超时最坏情况的问题。
我在寻找像一个定时器它在哪里可以更新延迟时间的解决方案。
有任何想法吗?
有n
其执行一些操作的对象。 执行操作后,时间戳将被更新。 现在我想实现一个超时线程从而验证如果时间戳比例如在60秒钟之前的较早。
我的第一个解决办法是做与线程(while循环+睡眠),它正在与包括最后的时间戳的所有对象的列表。 现在我有有在线程需要59秒加上睡眠时间来决定超时最坏情况的问题。
我在寻找像一个定时器它在哪里可以更新延迟时间的解决方案。
有任何想法吗?
我认为使用有等待一个监视器对象/通知是合理的(如果使用的是JDK> = 5则可以使用条件与AWAIT /信号)
想法很简单:
工作线程:
doYourActualWork();
synchronized(jobFinishedMonitor) {
updateTimestamp();
jobFinishedMonitor.notify();
}
超时线程:
synchronized(jobFinishedMonitor) {
while(within60Second(timestamp)) {
jobFinishedMonitor.wait(60);
}
if (within60Second(timestamp)) {
timeoutHappened=true;
}
}
if (timeoutHappened) {
// do timeout handling
}
对于这个问题,目前还不清楚你想要超时做什么。 在这里,我提出了两个选项来实现一个轻量级的超时:监控VS控制。
监测超时
对于全局计时器,你可以使用Timer
从JDK设施:
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(...)
立即并发执行(未预定),使其成为一个通用的执行机构,而不是一个专用的定时器功能。
在这两种情况下,你需要特别注意安全地从你的对象正在监视的超时值。 通常情况下,你将使用对象的一个synchronized方法,要求它的超时状态。
强迫超时
该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);
此方法返回之后,你可以问每一个未来是否规定的时间内取得了成功。
中断线程每次更新的时间戳时间。 然后,它会循环,发现无事可做,睡觉,如果不出意外发生了时间戳,使其过期。 如果它被中断,第二次,那就更好了。 并且在任何时候都应该永不睡眠的时间超过60负(当前时间减去最老的时间戳)。