Java ScheduledExecutorService 取消不起作用



我使用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中设置的时间段。

您需要在cancelMonitorTimer()方法中将true设置为timeCrtl.cancel(true)而不是timerCtrl.cancel(false)。如果任务成功取消,此函数将进一步返回布尔值true,但如果它返回false,则表示它已经完成。

我找到了在定义timerCtrl时不应该使用限定符static的原因。但我仍然不知道为什么不能。在我的理解中,静态值是每个类加载器而不是每个线程,因此该变量将在不同的线程之间共享。
此外,类Monitor是一个基类,它被另一个名为MonitorSon的类继承,并且该操作在子类中调用。

最新更新