java - 如何等待(固定速率)ScheduledFuture 在取消时完成

标签 java scheduledexecutorservice

是否有一种内置方法可以取消已通过 ScheduledExecutorService.scheduleAtFixedRate 以固定速率安排的 Runnable 任务,并在恰好发生时等待它完成调用取消时运行?

考虑以下示例:

public static void main(String[] args) throws InterruptedException, ExecutionException  {

    Runnable fiveSecondTask = new Runnable() {
        @Override
        public void run() {
            System.out.println("5 second task started");
            long finishTime = System.currentTimeMillis() + 5_000;
            while (System.currentTimeMillis() < finishTime);
            System.out.println("5 second task finished");
        }
    };

    ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
    ScheduledFuture<?> fut = exec.scheduleAtFixedRate(fiveSecondTask, 0, 1, TimeUnit.SECONDS);

    Thread.sleep(1_000);
    System.out.print("Cancelling task..");
    fut.cancel(true);

    System.out.println("done");
    System.out.println("isCancelled : " + fut.isCancelled());
    System.out.println("isDone      : " + fut.isDone());
    try {
        fut.get();
        System.out.println("get         : didn't throw exception");
    }
    catch (CancellationException e) {
        System.out.println("get         : threw exception");
    }
}

这个程序的输出是:

5 second task started
Cancelling task..done
isCancelled : true
isDone      : true
get         : threw exception
5 second task finished

设置一个共享的 volatile 标志似乎是最简单的选择,但我宁愿尽可能避免它。

java.util.concurrent 框架是否内置了此功能?

最佳答案

我不完全确定您想要达到什么目的,但是当我通过谷歌搜索来到这里时,我认为可能值得回答您的问题。

1) 如果你想强行停止繁重的工作量 - 不幸的是似乎没有解决方案(当线程不响应中断时)。处理它的唯一方法是在循环中的耗时操作之间插入 Thread.sleep(1) ( http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html ) - 也许 deamon thread 在这里会有所帮助,但我真的不鼓励使用它们。

2) 如果您想阻塞当前线程直到子线程完成,那么您可以使用 get http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#get() 而不是调用 cancel甚至超时。

3) 如果你想彻底取消子线程那么你可以调用:

fut.cancel(false);

这不会中断当前的执行,但不会安排它再次运行。

4)如果你的工作量不大,只需要等待5秒,那么使用thread sleep或者TimeUnit sleep。在这种情况下,中断/取消将立即生效。

此外,您的示例缺少对 Executor 的关闭调用,这会导致应用程序不停止。

关于java - 如何等待(固定速率)ScheduledFuture 在取消时完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23441640/

相关文章:

java - 如何在 Java 枚举中定义静态常量?

java - 为什么程序等待schedule()完成但不等待scheduleWithFixedDelay()?

java - 当线程中发生异常时,SchduledExecutorService 不执行 UncaughtExceptionHandler

java - 如何使用 ScheduledExecutorService 通过多个服务定期运行作业

java - 如何使用 ScheduledExecutorService 每天在特定时间运行特定任务?

java - ActiveMQ 5.x 和 DurableConsumer

java - 当我明确地将一些键绑定(bind)分配给另一个对象时,为什么我的所有键绑定(bind)仅适用于一个对象?

java - EditText On update/onChange value 添加监听器

java - 我不知道如何重置循环(请参见示例)

java - Java中的ScheduledExecutorService和线程