<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    paulwong

    Scheduling a task in Java within a CompletableFuture

    When we want to do something later in our Java code, we often turn to the ScheduledExecutorService. This class has a method called schedule(), and we can pass it some code to be run later like this:

    ScheduledExecutorService executor =
        Executors.newScheduledThreadPool(4);
    executor.schedule(
        () -> {System.out.println("..later");},
        1,
        TimeUnit.SECONDS
    );
    System.out.println("do");
    // (Don't forget to shut down the executor later)

    The above code prints “do…” and then one second later it prints “…later”.

    We can even write code that does some work and returns a result in a similar way:

    // (Make the executor as above.)
    ScheduledFuture future = executor.schedule(
        () -> 10 + 25, 1, TimeUnit.SECONDS);
    System.out.println("answer=" + future.get())


    The above code prints “answer=35”. When we call get() it blocks waiting for the scheduler to run the task and mark the ScheduledFuture as complete, and then returns the answer to the sum (10 + 25) when it is ready.

    This is all very well, but you may note that the Future returned from schedule() is a ScheduledFuture, and a ScheduledFuture is not a CompletableFuture.

    Why do you care? Well, you might care if you want to do something after the scheduled task is completed. Of course, you can call get(), and block, and then do something, but if you want to react asynchronously without blocking, this won’t work.

    The normal way to run some code after a Future has completed is to call one of the “then*” or “when*” methods on the Future, but these methods are only available on CompletableFuture, not ScheduledFuture.

    Never fear, we have figured this out for you. We present a small wrapper for schedule that transforms your ScheduledFuture into a CompletableFuture. Here’s how to use it:

    CompletableFuture<Integer> future =
        ScheduledCompletable.schedule(
            executor,
            () -> 10 + 25,
            1,
            TimeUnit.SECONDS
         );
    future.thenAccept(
        answer -> {System.out.println(answer);}
    );
    System.out.println("Answer coming")


    The above code prints “Answer coming…” and then “35”, so we can see that we don’t block the main thread waiting for the answer to come back.

    So far, we have scheduled a synchronous task to run in the background after a delay, and wrapped its result in a CompletableFuture to allow us to chain more tasks after it.

    In fact, what we often want to do is schedule a delayed task that is itself asynchronous, and already returns a CompletableFuture. In this case it feels particularly natural to get the result back as a CompletableFuture, but with the current ScheduledExecutorService interface we can’t easily do it.

    It’s OK, we’ve figured that out too:

    Supplier<CompletableFuture<Integer>> asyncTask = () ->
        CompletableFuture.completedFuture(10 + 25);
    CompletableFuture<Integer> future =
        ScheduledCompletable.scheduleAsync(
            executor, asyncTask, 1, TimeUnit.SECONDS);
    future.thenAccept(
        answer -> {System.out.println(answer);}
    );
    System.out.println("Answer coming")


    The above code prints “Answer coming…” and then “35”, so we can see that our existing asynchronous task was scheduled in the background, and we didn’t have to block the main thread waiting for it. Also, under the hood, we are not blocking the ScheduledExecutorService‘s thread (from its pool) while the async task is running – that task just runs in whatever thread it was assigned when it was created. (Note: in our example we don’t really run an async task at all, but just immediately return a completed Future, but this does work for real async tasks.)

    I know you’re wondering how we achieved all this. First, here’s how we run a simple blocking task in the background and wrap it in a CompletableFuture:

    public static <T> CompletableFuture<T> schedule(
        ScheduledExecutorService executor,
        Supplier<T> command,
        long delay,
        TimeUnit unit
    ) {
        CompletableFuture<T> completableFuture = new CompletableFuture<>();
        executor.schedule(
            (() -> {
                try {
                    return completableFuture.complete(command.get());
                } catch (Throwable t) {
                    return completableFuture.completeExceptionally(t);
                }
            }),
            delay,
            unit
        );
        return completableFuture;
    }


    And here’s how we delay execution of an async task but still return its result in a CompletableFuture:

    public static <T> CompletableFuture<T> scheduleAsync(
        ScheduledExecutorService executor,
        Supplier<CompletableFuture<T>> command,
        long delay,
        TimeUnit unit
    ) {
        CompletableFuture<T> completableFuture = new CompletableFuture<>();
        executor.schedule(
            (() -> {
                command.get().thenAccept(
                    t -> {completableFuture.complete(t);}
                )
                .exceptionally(
                    t -> {completableFuture.completeExceptionally(t);return null;}
                );
            }),
            delay,
            unit
        );
        return completableFuture;
    }


    Note that this should all work to run methods like exceptionally()thenAccept()whenComplete() etc.

    Feedback and improvements welcome!


    https://www.artificialworlds.net/blog/2019/04/05/scheduling-a-task-in-java-within-a-completablefuture/

    posted on 2020-08-24 09:06 paulwong 閱讀(394) 評論(0)  編輯  收藏 所屬分類: J2SE多線程

    主站蜘蛛池模板: 亚洲日本一区二区一本一道| 亚洲午夜在线一区| 免费精品无码AV片在线观看| 亚洲一区二区三区免费视频 | 久草免费福利视频| 亚洲AV成人噜噜无码网站| 免费国产综合视频在线看| 免费日本一区二区| 亚洲av第一网站久章草| 亚洲av午夜成人片精品网站| 成人毛片18女人毛片免费96| 中文字幕成人免费高清在线| 亚洲深深色噜噜狠狠网站| 国产亚洲自拍一区| 好爽…又高潮了免费毛片| a级毛片在线视频免费观看| 亚洲精品人成网在线播放影院| 亚洲国产高清在线一区二区三区| 日本在线看片免费人成视频1000| 老子影院午夜伦不卡亚洲| 亚洲人成电影福利在线播放| 国产免费变态视频网址网站| 久久国产高潮流白浆免费观看| 春暖花开亚洲性无区一区二区| 亚洲精品在线免费观看| 中文字幕亚洲专区| 香蕉高清免费永久在线视频| 99久热只有精品视频免费看 | 中文字幕亚洲男人的天堂网络| 中文字幕在亚洲第一在线| 成人au免费视频影院| 毛片在线全部免费观看| 老司机午夜精品视频在线观看免费| 亚洲黄色免费网站| 国产AV无码专区亚洲AV漫画| 免费看无码自慰一区二区| 1区2区3区产品乱码免费| a在线观看免费视频| 无遮挡呻吟娇喘视频免费播放| 在线综合亚洲欧洲综合网站| 久久丫精品国产亚洲av|