<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 閱讀(395) 評論(0)  編輯  收藏 所屬分類: J2SE多線程

    主站蜘蛛池模板: 久久久久久亚洲精品成人| 亚洲人妖女同在线播放| 成人浮力影院免费看| 亚洲乱码在线播放| 亚洲Aⅴ无码一区二区二三区软件 亚洲AⅤ视频一区二区三区 | 国产免费一区二区三区在线观看| 亚洲AV无码乱码国产麻豆| 一区二区三区免费电影| 亚洲免费在线播放| 四虎影永久在线高清免费| 亚洲码和欧洲码一码二码三码| 久久久精品2019免费观看 | 免费无码午夜福利片69| 亚洲AV无码1区2区久久| 国产猛男猛女超爽免费视频| 亚洲日本国产精华液| jjzz亚洲亚洲女人| 91精品国产免费久久国语麻豆| 精品国产_亚洲人成在线| 亚洲国产国产综合一区首页| 日本不卡免费新一二三区| 日本视频在线观看永久免费| 激情无码亚洲一区二区三区| 亚洲成年轻人电影网站www| 免费不卡中文字幕在线| 亚欧人成精品免费观看| 亚洲国产精品免费观看 | 久久亚洲精品国产精品黑人| 免费看a级黄色片| 中文字幕在线免费观看| 精品国产污污免费网站入口在线| 华人在线精品免费观看| 久久亚洲精品11p| 国产成人亚洲影院在线观看| 九九热久久免费视频| 亚洲人成色77777在线观看 | 99久久亚洲精品无码毛片| 久久精品亚洲乱码伦伦中文| 成人免费看片又大又黄| 久久久久免费看成人影片| 久久国产乱子伦精品免费午夜|