我使用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
设置的时间段
答案 0 :(得分:0)
您需要在 cancelMonitorTimer()方法中将{true}设置为timeCrtl.cancel(true)
而不是timerCtrl.cancel(false)
。如果任务被成功取消但是如果它返回 false ,则此函数进一步返回布尔值 true ,这意味着它已经完成。
答案 1 :(得分:0)
我找到了在定义timerCtrl
时不应使用限定符Monitor
的原因。但我仍然不知道为什么不能。根据我的理解,静态值是每个类加载器而不是per-thread,因此该变量将在不同的线程之间共享。
此外,类MonitorSon
是一个基类,由另一个名为{{1}}的类继承,并在子类中调用该操作。