【发布时间】:2017-03-02 05:56:25
【问题描述】:
我使用ScheduledExecutorService 启动了一个定期运行的计时器,但是在我调用cancel() 后,这个计时器无法取消:
import java.util.concurrent.*;
public class Monitor {
private static ScheduledFuture<?> timerCtrl;
private final ScheduledExecutorService scheduExec = Executors.newScheduledThreadPool(1, StatmonitorThreadFactory.getInstance());
private void startTimer() {
timerCtrl = scheduExec.scheduleAtFixedRate(new MonitorTimer(), 5, 5, TimeUnit.SECONDS);
}
public boolean cancelMonitorTimer() {
if (timerCtrl != null) {
timerCtrl.cancel(false); //both timerCtrl.isDone() and timerCtrl.isCancelled() return true
LOG.error("{} {}", timerCtrl.isDone(), timerCtrl.isCancelled());
if (!timerCtrl.isCancelled()) {
LOG.error("timerCtrl cancel failed!");
return false;
}
}
return true;
}
private class MonitorTimer implements Runnable {
@Override
public void run() {
doPeriodicMonitor(); //call another function
}
}
}
首先,我打电话给startTimer() 来启动我的计时器。过了一会儿,我调用cancelMonitorTimer取消并停止这个定时器,函数返回true,但定时器仍然运行,doPeriodicMonitor每5秒调用一次,这是我在startTimer中设置的一个周期。
【问题讨论】:
-
如果监视任务花费的时间超过 5 秒并且线程池已耗尽,这将是预期的行为。您应该添加日志记录以记录
doPeriodicMonitor的延迟,然后确保计划的速率较慢。您还应该在没有线程池的情况下尝试它以排除那里的错误。 -
@Gene 在
doPeriodicMonitor(),我启动另外两个线程来做一些工作,是非法的吗?