ScheduledExecutorService dataService = Executors.newScheduledThreadPool(1); Future<?> dataTimerHandle = dataService.scheduleAtFixedRate(runnable, 100, freq, TimeUnit.MILLISECONDS);
这很好用,没有缺陷。
但是,当某个标志因用户操作而变为 true
时,任务不再需要定期执行,只需执行一次即可。然后,我尝试取消任务并仅提交一次,如下所示:
if(!dynamicUpdate) { dataTimerHandle.cancel(true); dataTimerHandle = dataService.submit(runnable); } else { //Reschedule again: dataTimerHandle = dataService.scheduleAtFixedRate(runnable, 100, freq, TimeUnit.MILLISECONDS); }
但似乎 runnable 仍在定期执行, cancel()
未按预期工作。 是否有替代策略?
最佳答案
问题可能不在 Future 的 cancel()
方法中。这是一个可运行的小示例,它似乎完全符合您的要求:
import java.util.concurrent.*; public class CancelPeriodicTask { public static void main(String[] args) { ScheduledThreadPoolExecutor scheduler = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(1); scheduler.setRemoveOnCancelPolicy(true); try { new CancelPeriodicTask().test(scheduler); } catch (Exception e) { e.printStackTrace(); } finally { int openTasks = scheduler.shutdownNow().size(); println("Finished, open tasks: " + openTasks); // openTasks will be 1 when RemoveOnCancelPolicy is false // and the executor is closed within the scheduled task-period. } } private static long sleepTime = 25L; public void test(ScheduledThreadPoolExecutor scheduler) throws Exception { // sleep 5 times at scheduled interval SleepTask sleepTask; ScheduledFuture<?> scheduledSleep = scheduler.scheduleAtFixedRate(sleepTask = new SleepTask(), 0, 2 * sleepTime, TimeUnit.MILLISECONDS); sleepTask.sleepTimes.await(); println("Cancelling scheduledSleep. Done: " + scheduledSleep.isDone() + ", cancelled: " + scheduledSleep.isCancelled()); scheduledSleep.cancel(true); Thread.sleep(2 * sleepTime); println("Running sleepTask once."); scheduler.submit(sleepTask); Thread.sleep(2 * sleepTime); scheduledSleep = scheduler.scheduleAtFixedRate(sleepTask, 0, 2 * sleepTime, TimeUnit.MILLISECONDS); println("Re-scheduled scheduledSleep. Done: " + scheduledSleep.isDone() + ", cancelled: " + scheduledSleep.isCancelled()); Thread.sleep(5 * sleepTime); println("Cancelling scheduledSleep. Done: " + scheduledSleep.isDone() + ", cancelled: " + scheduledSleep.isCancelled()); scheduledSleep.cancel(true); } class SleepTask implements Runnable { public final CountDownLatch sleepTimes = new CountDownLatch(5); public int sleepCount; @Override public void run() { println("Sleeping " + (++sleepCount)); try { Thread.sleep(sleepTime); } catch (Exception e) { e.printStackTrace(); } sleepTimes.countDown(); } } private static final long START_TIME = System.currentTimeMillis(); private static void println(String msg) { System.out.println((System.currentTimeMillis() - START_TIME) + "\t " + msg); } }
关于java - Future.cancel() 没有取消 ScheduledExecutorService 的计划执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29181905/