如果从scheduleWithFixedDelay / scheduleAtFixedRate方法检索ScheduledFuture.get()方法的目的是什么

时间:2014-07-31 00:16:39

标签: java java.util.concurrent

我对以下

感到困惑

我知道,如果我使用schedule类中的ScheduledThreadPoolExecutor方法:

ScheduledFuture<?> scheduledFuture = 
scheduledThreadPoolExecutor.schedule(myClassRunnable, 5, TimeUnit.SECONDS);

我可以稍后检索 scheduledFuture.get(5, TimeUnit.SECONDS)scheduledFuture.get()并且应该 null ,因为该任务只执行了一次并且已完成。 并且 null 因为我使用的是shedule's Runnable方法版本而不是shedule's Callable方法版本。它符合API

直到这里我很好。

我的问题:

ScheduledFuture(甚至来自scheduleWithFixedDelay)方法检索scheduleAtFixedRate的目的是什么:

ScheduledFuture<?> scheduledFuture= 
scheduledThreadPoolExecutor.scheduleWithFixedDelay(myClassRunnable, 1, 5, TimeUnit.SECONDS);

是的,我知道两个 fixed 方法多次执行相同的任务,直到调用ScheduledThreadPoolExecutor's shutdown方法(它必须停止所有已安排的任务)。

我通过Google进行了一项研究,使用从ScheduledFuture返回的scheduleWithFixedDelay来查找一些示例,我只找到一个使用取消方法取消特定任务的示例。但没有人使用获取

我不知道我是不是错了,但如果我们使用scheduleWithFixedDelay,那么 get 方法似乎毫无用处,因为如果我以后再使用的话:

  • scheduledFuture.get() - 它仍然在等待,Runnable对象仍然可以工作多次(运行,完成,延迟,运行等等)。
  • scheduledFuture.get(32,TimeUnit.SECONDS) - 始终显示TimeoutException

我认为我应该能够检索空值,因为我可以使用period方法中的scheduleWithFixedDelay参数/参数。 我的意思是:运行Runnable对象,等待它完成并使用scheduledFuture.get()获取确认已完成的空值,等待延迟时间再次运行Runnable对象根据period值等....

非常欢迎澄清和示例

提前致谢。

4 个答案:

答案 0 :(得分:1)

ScheduledFuture可用于在下一个任务执行之前留出时间:

    ScheduledFuture<?> f = Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
        public void run() {
            System.out.println("run");
        }
    }, 0, 10000, TimeUnit.MILLISECONDS);
    Thread.sleep(1000);
    System.out.println("Time left before next run " + f.getDelay(TimeUnit.MILLISECONDS));

打印

run
Time left before next run 8999

答案 1 :(得分:1)

我使用以下代码进行了尝试:

ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
AtomicInteger count = new AtomicInteger(0);
Runnable task = () -> {
    int currentCount = count.incrementAndGet();
    System.out.println("Task #" + currentCount + " started");
    if (currentCount == 2) {
        System.out.println("Shutting down scheduler...");
        scheduler.shutdown();
    }
    try {
        Thread.sleep(1000);
    } catch (InterruptedException ie) {
        throw new RuntimeException(ie);
    }
    System.out.println("Task #" + currentCount + " finished");
};

System.out.println("Starting scheduler...");
ScheduledFuture<?> scheduledFuture = scheduler.scheduleWithFixedDelay(
    task, 0, 2, TimeUnit.SECONDS);
System.out.println("Getting scheduled future...");
System.out.println(scheduledFuture.get());        
System.out.println("End of code reached.");

以下是输出:

Exception in thread "main" java.util.concurrent.CancellationException
    at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:121)
    at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
    at Rextester.main(source.java:33)
Starting scheduler...
Getting scheduled future...
Task #1 started
Task #1 finished
Task #2 started
Shutting down scheduler...
Task #2 finished

在线Rextester演示https://rextester.com/LYKN32123

不确定这有什么用,但是如果调度程序关闭,它会显示get()方法抛出CancellationException

答案 2 :(得分:0)

我认为,在使用.scheduleWithFixedDelay(...)(或scheduleAtFixedRate(...))的情况下,返回的get()的{​​{1}}方法确实确实很奇怪。

我相信您永远不会从ScheduledFuture<?>方法中收到任何信息,只是希望在取消Runnable时会从中抛出异常。

当然可以看到一个用例;-)

请参阅JavaDoc

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ScheduledExecutorService.html#scheduleAtFixedRate-java.lang.Runnable-long-long-java.util.concurrent.TimeUnit-

  

返回:   代表待完成任务的ScheduledFuture,其get()方法将在取消时引发异常

答案 3 :(得分:-1)

使用cheduleFuture.get(),您可以获取任务的句柄,并且如果需要从UserInterface手动取消任务或根据某些条件(例如null)取消任务,可以使用该句柄将其取消。