我使用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
的类继承,并且该操作在子类中调用。