多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
### 模拟 作为使用 `CompletableFuture` 将一系列操作组合的示例,让我们模拟一下制作蛋糕的过程。在第一阶段,我们准备并将原料混合成面糊: ```java // concurrent/Batter.java import java.util.concurrent.*; import onjava.Nap; public class Batter { static class Eggs { } static class Milk { } static class Sugar { } static class Flour { } static <T> T prepare(T ingredient) { new Nap(0.1); return ingredient; } static <T> CompletableFuture<T> prep(T ingredient) { return CompletableFuture .completedFuture(ingredient) .thenApplyAsync(Batter::prepare); } public static CompletableFuture<Batter> mix() { CompletableFuture<Eggs> eggs = prep(new Eggs()); CompletableFuture<Milk> milk = prep(new Milk()); CompletableFuture<Sugar> sugar = prep(new Sugar()); CompletableFuture<Flour> flour = prep(new Flour()); CompletableFuture .allOf(eggs, milk, sugar, flour) .join(); new Nap(0.1); // Mixing time return CompletableFuture.completedFuture(new Batter()); } } ``` 每种原料都需要一些时间来准备。`allOf()` 等待所有的配料都准备好,然后使用更多些的时间将其混合成面糊。接下来,我们把单批面糊放入四个平底锅中烘烤。产品作为 `CompletableFutures` 流返回: ```java // concurrent/Baked.java import java.util.concurrent.*; import java.util.stream.*; import onjava.Nap; public class Baked { static class Pan { } static Pan pan(Batter b) { new Nap(0.1); return new Pan(); } static Baked heat(Pan p) { new Nap(0.1); return new Baked(); } static CompletableFuture<Baked> bake(CompletableFuture<Batter> cfb) { return cfb .thenApplyAsync(Baked::pan) .thenApplyAsync(Baked::heat); } public static Stream<CompletableFuture<Baked>> batch() { CompletableFuture<Batter> batter = Batter.mix(); return Stream.of( bake(batter), bake(batter), bake(batter), bake(batter) ); } } ``` 最后,我们制作了一批糖,并用它对蛋糕进行糖化: ```java // concurrent/FrostedCake.java import java.util.concurrent.*; import java.util.stream.*; import onjava.Nap; final class Frosting { private Frosting() { } static CompletableFuture<Frosting> make() { new Nap(0.1); return CompletableFuture .completedFuture(new Frosting()); } } public class FrostedCake { public FrostedCake(Baked baked, Frosting frosting) { new Nap(0.1); } @Override public String toString() { return "FrostedCake"; } public static void main(String[] args) { Baked.batch().forEach( baked -> baked .thenCombineAsync(Frosting.make(), (cake, frosting) -> new FrostedCake(cake, frosting)) .thenAcceptAsync(System.out::println) .join()); } } ``` 一旦你习惯了这种背后的想法, `CompletableFuture` 它们相对易于使用。