`Java 8 in Action` is wrong about the demo it provided?

后端 未结 1 1238
盖世英雄少女心
盖世英雄少女心 2021-01-05 22:41

This code is a quoted from Java 8 in Action, which is also in the book 11.4.3.

public Stream> findPricesStream(String p         


        
相关标签:
1条回答
  • 2021-01-05 23:33

    As a first note, that code is distracting from what’s happening due to the unnecessary splitting into multiple Stream operations.

    Further, there is no sense in doing

    future.thenCompose(quote ->
        CompletableFuture.supplyAsync(() -> Discount.applyDiscount(quote), executor))
    

    instead of

    future.thenApplyAsync(quote -> Discount.applyDiscount(quote), executor)
    

    So, a simpler example doing the same would be

    public Stream<CompletableFuture<String>> findPricesStream(String product) {
        return shops.stream().map(
            shop -> CompletableFuture
                .supplyAsync(() -> shop.getPrice(product), executor)
                .thenApply(Quote::parse)
                .thenApplyAsync(quote -> Discount.applyDiscount(quote), executor));
    }
    

    However, you are right, there is no guaranty that getPrice and applyDiscount run in the same thread—unless the executor is a single threaded executor.

    You may interpret “executor thread” as “one of the executor’s threads”, but even then, there in a dangerously wrong point in the diagram, namely, “new Quote(price)”, which apparently actually means “Quote::parse”. That step does not belong to the right side, as the actual thread evaluating the function passed to thenApply is unspecified. It may be one of the executor’s threads upon completion of the previous stage, but it may also be “your thread” right when calling thenApply, e.g. if the asynchronous operation managed to complete in‑between.

    The CompletableFuture offers no way to enforce the use of the first stage’s completing thread for the dependent actions.

    Unless you use a simple sequential code instead, of course:

    public Stream<CompletableFuture<String>> findPricesStream(String product) {
        return shops.stream().map(shop -> CompletableFuture
            .supplyAsync(() -> Discount.applyDiscount(Quote.parse(shop.getPrice(product))), executor));
    }
    

    Then, the picture of a linear thread on the right hand side will be correct.

    0 讨论(0)
提交回复
热议问题