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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25049021/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 07:13:05  来源:igfitidea点击:

What is the purpose of ScheduledFuture.get() method if is retrieved from the scheduleWithFixedDelay/scheduleAtFixedRate method

javajava.util.concurrent

提问by Manuel Jordan

I am confused with the following.

我对以下内容感到困惑。

I know, if I use the schedulemethod from the ScheduledThreadPoolExecutorclass:

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

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

I am able to retrieve later the valuethrough scheduledFuture.get(5, TimeUnit.SECONDS)or scheduledFuture.get()and it should be nullbecause the task has been executed just only once and it is completed. And nullbecause I am working with the Runnableschedulemethod version and not with the Callableschedulemethod version. It according with the API.

我可以稍后通过 or检索该,这应该是因为该任务仅执行了一次并且已完成。而且因为我正在使用方法版本而不是方法版本。它符合API。scheduledFuture.get(5, TimeUnit.SECONDS)scheduledFuture.get()nullnullRunnablescheduleCallableschedule

Until here I am fine.

直到这里我很好。

My question:

我的问题:

What is the purpose of ScheduledFutureif is retrieved from the scheduleWithFixedDelay(even from scheduleAtFixedRate) method:

ScheduledFuturescheduleWithFixedDelay(甚至 from scheduleAtFixedRate)方法中检索 if的目的是什么:

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

Yes, I know both fixedmethods execute the same task many times until the ScheduledThreadPoolExecutor's shutdownmethod is called (it must stop all the tasks scheduled).

是的,我知道这两个固定方法多次执行相同的任务,直到ScheduledThreadPoolExecutor's shutdown调用该方法(它必须停止所有计划的任务)。

I did a research through Google looking for some examples using ScheduledFuturereturned from scheduleWithFixedDelay, I only found one using the cancelmethod, to cancel a specific task. But none working with get().

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

I don't know if I am wrong, but seems useless the get()method if we are working with scheduleWithFixedDelay, because if I use later:

我不知道我是否错了,但get()如果我们正在使用该方法似乎没用scheduleWithFixedDelay,因为如果我以后使用:

  • scheduledFuture.get()- it remains awaiting and the Runnableobject remains working many times (run,complete,delay,run,etc... )
  • scheduledFuture.get(32, TimeUnit.SECONDS)- always gives a TimeoutException
  • scheduledFuture.get()- 它仍在等待并且Runnable对象仍然工作多次(运行、完成、延迟、运行等...)
  • scheduledFuture.get(32, TimeUnit.SECONDS)- 总是给出一个 TimeoutException

I thought I should be able to retrieve the nullvalue since I can use the periodargument/parameter from the scheduleWithFixedDelaymethod. I.e: Run the Runnable object, wait until it completes and use the scheduledFuture.get()to get the nullvalue that confirms it has been completed, await the period of the delay time to run again the Runnableobject according with the periodvalue etc....

我认为我应该能够检索该null值,因为我可以使用方法中的period参数/参数scheduleWithFixedDelay。即:运行Runnable object,等待完成并使用scheduledFuture.get()来获取null确认它已经完成的值,等待延迟时间段再次运行Runnable符合该period值的对象等......

Clarifications and examples are totally welcome.

完全欢迎澄清和示例。

采纳答案by Evgeniy Dorofeev

ScheduledFuture can be used to get time left before next task execution:

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));

prints

印刷

run
Time left before next run 8999

回答by Julien

I would think that in the case of using .scheduleWithFixedDelay(...)(or scheduleAtFixedRate(...)), the get()method of the returned ScheduledFuture<?>feels indeed as an odd fit.

我认为在使用.scheduleWithFixedDelay(...)(or scheduleAtFixedRate(...))的情况下,get()返回的方法ScheduledFuture<?>确实感觉很奇怪。

I believe you won't ever receive anything from the get()method, just expect an exception to be thrown from it, when Runnable is cancelled.

我相信您永远不会从该get()方法中收到任何信息,只是期望在取消 Runnable 时从中抛出异常。

Surely one can see a use-case for this ;-)

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

see JavaDoc

见 JavaDoc

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

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

Returns: a ScheduledFuture representing pending completion of the task, and whose get() method will throw an exception upon cancellation

返回: 一个 ScheduledFuture 表示任务的等待完成,其 get() 方法将在取消时抛出异常

回答by Steve Chambers

I tried this out with the following code:

我用以下代码尝试了这一点:

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.");

Here is the output:

这是输出:

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

Online Rextester Demo:https://rextester.com/LYKN32123

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

Not sure how useful this is but it shows the get()method throws a CancellationExceptionif the scheduler is shut down.

不确定这有多大用处,但它显示如果调度程序关闭,该get()方法会抛出 a CancellationException

回答by randeepsp

Using scheduledFuture.get() you can get a handle to the task, and in case this task needs to be cancelled say manually from the UserInterface or based on some conditions like the null, the handle can be used to cancel it.

使用 ScheduledFuture.get() 可以获得任务的句柄,如果需要从 UserInterface 手动取消此任务,或者基于某些条件(如 null),则可以使用句柄取消它。