title: `Java 8 in Action` is wrong about the demo it provided?
body: <p>This code is a quoted from <a href="https://github.com/java8/Java8InAction/blob/master/src/main/java/lambdasinaction/chap11/BestPriceFinder.java" rel="nofollow noreferrer">Java 8 in Action</a>, which is also in the book 11.4.3.</p>
  
  <pre><code>public Stream&lt;CompletableFuture&lt;String&gt;&gt; findPricesStream(String product) {
      return shops.stream()
              .map(shop -&gt; CompletableFuture.supplyAsync(() -&gt; shop.getPrice(product), executor))
              .map(future -&gt; future.thenApply(Quote::parse))
              .map(future -&gt; future.thenCompose(quote -&gt; CompletableFuture.supplyAsync(() -&gt; Discount.applyDiscount(quote), executor)));
  }
  </code></pre>
  
  <p>Along the code, the writer enclose a <strong>figure</strong> as follows expressing that the <code>applyDiscount()</code> works in the same thread with <code>getPrice()</code>, which I strongly have a doubt: there are two different <strong>Async</strong> suffix here which means the second call should be in <strong>another</strong> thread. </p>
  
  <p><a href="https://i.stack.imgur.com/oBNsU.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/oBNsU.png" alt="enter image description here"></a></p>
  
  <p>I tested it locally with the following code:</p>
  
  <pre><code>private static void testBasic() {
      out.println("*****************************************");
      out.println("********** TESTING thenCompose **********");
      CompletableFuture[] futures = IntStream.rangeClosed(0, LEN).boxed()
              .map(i -&gt; CompletableFuture.supplyAsync(() -&gt; runStage1(i), EXECUTOR_SERVICE))
              .map(future -&gt; future.thenCompose(i -&gt; CompletableFuture.supplyAsync(() -&gt; runStage2(i), EXECUTOR_SERVICE)))
              .toArray(size -&gt; new CompletableFuture[size]);
      CompletableFuture.allOf(futures).join();
  }
  </code></pre>
  
  <p>The output further demonstrate my thought, is it correct? </p>
  
  <pre><code>*****************************************
  ********** TESTING thenCompose **********
  Start: stage - 1 - value: 0 - thread name: pool-1-thread-1
  Start: stage - 1 - value: 1 - thread name: pool-1-thread-2
  Start: stage - 1 - value: 2 - thread name: pool-1-thread-3
  Start: stage - 1 - value: 3 - thread name: pool-1-thread-4
  Finish: stage - 1 - value: 3 - thread name: pool-1-thread-4 - time cost: 1520
  Start: stage - 2 - value: 3 - thread name: pool-1-thread-5
  Finish: stage - 1 - value: 0 - thread name: pool-1-thread-1 - time cost: 1736
  Start: stage - 2 - value: 0 - thread name: pool-1-thread-6
  Finish: stage - 1 - value: 2 - thread name: pool-1-thread-3 - time cost: 1761
  Start: stage - 2 - value: 2 - thread name: pool-1-thread-7
  Finish: stage - 2 - value: 2 - thread name: pool-1-thread-7 - time cost: 446
  Finish: stage - 1 - value: 1 - thread name: pool-1-thread-2 - time cost: 2249
  Start: stage - 2 - value: 1 - thread name: pool-1-thread-8
  Finish: stage - 2 - value: 3 - thread name: pool-1-thread-5 - time cost: 828
  Finish: stage - 2 - value: 0 - thread name: pool-1-thread-6 - time cost: 704
  Finish: stage - 2 - value: 1 - thread name: pool-1-thread-8 - time cost: 401
  </code></pre>
  
  <p>The <code>Java 8 in Action</code> is wrong about this? </p>
  
  <p>Thank you, @Holger. You make it crystal clear to me now about the <strong>executing thread</strong> for <strong>async</strong> and <strong>non-async</strong> methods. Especially after checking its <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html" rel="nofollow noreferrer">specification</a> further demonstrating your point. </p>
  
  <blockquote>
    <p>Actions supplied for dependent completions of <strong>non-async</strong> methods <strong>may</strong> be performed by the thread that completes the current CompletableFuture, or by any other caller of a completion method.</p>
  </blockquote>