Java ScheduledExecutorService取消不起作用

时间:2017-03-02 05:56:26

标签: java timer

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

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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