From bbae248de3137347fec6fcb5f752da228d926893 Mon Sep 17 00:00:00 2001 From: yecllsl Date: Mon, 11 Sep 2017 16:36:38 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E7=AE=80=E5=8D=95=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 ++ src/main/java/lambdasinaction/chap7/ParallelStreams.java | 2 +- src/main/java/lambdasinaction/chap7/ParallelStreamsHarness.java | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index b7d7ac33..d6271bcc 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ # Repository wide ignore mac DS_Store files .DS_Store +*.lck +*.log diff --git a/src/main/java/lambdasinaction/chap7/ParallelStreams.java b/src/main/java/lambdasinaction/chap7/ParallelStreams.java index e8b2a520..7443d821 100644 --- a/src/main/java/lambdasinaction/chap7/ParallelStreams.java +++ b/src/main/java/lambdasinaction/chap7/ParallelStreams.java @@ -17,7 +17,7 @@ public static long sequentialSum(long n) { } public static long parallelSum(long n) { - return Stream.iterate(1L, i -> i + 1).limit(n).parallel().reduce(Long::sum).get(); + return Stream.iterate(1L, i -> i + 1).limit(n).parallel().reduce(Long::sum).get();//并行处理流 } public static long rangedSum(long n) { diff --git a/src/main/java/lambdasinaction/chap7/ParallelStreamsHarness.java b/src/main/java/lambdasinaction/chap7/ParallelStreamsHarness.java index 7d53c86f..1101ed89 100644 --- a/src/main/java/lambdasinaction/chap7/ParallelStreamsHarness.java +++ b/src/main/java/lambdasinaction/chap7/ParallelStreamsHarness.java @@ -6,7 +6,7 @@ public class ParallelStreamsHarness { public static final ForkJoinPool FORK_JOIN_POOL = new ForkJoinPool(); - + //测试并行的时间 public static void main(String[] args) { System.out.println("Iterative Sum done in: " + measurePerf(ParallelStreams::iterativeSum, 10_000_000L) + " msecs"); System.out.println("Sequential Sum done in: " + measurePerf(ParallelStreams::sequentialSum, 10_000_000L) + " msecs"); From 1d73364e17f3010e3b6ec4a2e8195061969aa73f Mon Sep 17 00:00:00 2001 From: yecllsl Date: Mon, 11 Sep 2017 18:10:30 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chap7/ForkJoinSumCalculator.java | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/main/java/lambdasinaction/chap7/ForkJoinSumCalculator.java b/src/main/java/lambdasinaction/chap7/ForkJoinSumCalculator.java index 8f74a90a..e2d72548 100644 --- a/src/main/java/lambdasinaction/chap7/ForkJoinSumCalculator.java +++ b/src/main/java/lambdasinaction/chap7/ForkJoinSumCalculator.java @@ -6,39 +6,39 @@ import static lambdasinaction.chap7.ParallelStreamsHarness.FORK_JOIN_POOL; -public class ForkJoinSumCalculator extends RecursiveTask { +public class ForkJoinSumCalculator extends RecursiveTask {//继承RecursiveTask来创建可以用于分支/合并的框架 - public static final long THRESHOLD = 10_000; + public static final long THRESHOLD = 10_000;//不再将任务分解位子任务的数组大小 - private final long[] numbers; - private final int start; - private final int end; + private final long[] numbers;//要求和的数组 + private final int start;//子任务处理数组的起始位置和 + private final int end;//结束位置 - public ForkJoinSumCalculator(long[] numbers) { + public ForkJoinSumCalculator(long[] numbers) {//公共构造函数用于创建主任务 this(numbers, 0, numbers.length); } - private ForkJoinSumCalculator(long[] numbers, int start, int end) { + private ForkJoinSumCalculator(long[] numbers, int start, int end) {//私有构造函数用于递归的方式为主任务创建子任务 this.numbers = numbers; this.start = start; this.end = end; } @Override - protected Long compute() { - int length = end - start; - if (length <= THRESHOLD) { - return computeSequentially(); + protected Long compute() {//覆盖RecursiveTask抽象方法 + int length = end - start;//该任务负责求和部分的大小 + if (length <= THRESHOLD) {//如果小于阀值 + return computeSequentially();//顺序计算 } - ForkJoinSumCalculator leftTask = new ForkJoinSumCalculator(numbers, start, start + length/2); - leftTask.fork(); - ForkJoinSumCalculator rightTask = new ForkJoinSumCalculator(numbers, start + length/2, end); - Long rightResult = rightTask.compute(); - Long leftResult = leftTask.join(); - return leftResult + rightResult; + ForkJoinSumCalculator leftTask = new ForkJoinSumCalculator(numbers, start, start + length/2);//创建一个子任务为数组的前一半求和 + leftTask.fork();//利用ForkJoinPool另一个线程异步执行新建的子任务 + ForkJoinSumCalculator rightTask = new ForkJoinSumCalculator(numbers, start + length/2, end);//创建一个子任务为数组的后一半求和 + Long rightResult = rightTask.compute();//同步执行第二个子任务,有可能允许进一步递归划分 + Long leftResult = leftTask.join();//都区第一个任务的结果,如果尚未完成就等待 + return leftResult + rightResult;//该任务的结果是两个子任务结果的组合 } - private long computeSequentially() { + private long computeSequentially() {//在子任务不再可分时计算结果的简单算法 long sum = 0; for (int i = start; i < end; i++) { sum += numbers[i]; From aeff910bb6bc34c3a8ef2597ac94164338ed87ed Mon Sep 17 00:00:00 2001 From: yecllsl Date: Fri, 15 Sep 2017 16:19:57 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=BF=85=E8=A6=81?= =?UTF-8?q?=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/lambdasinaction/chap11/v1/Shop.java | 8 ++++---- .../lambdasinaction/chap11/v1/ShopMain.java | 4 ++-- .../java/lambdasinaction/chap7/WordCount.java | 20 +++++++++---------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/java/lambdasinaction/chap11/v1/Shop.java b/src/main/java/lambdasinaction/chap11/v1/Shop.java index cd3da975..af557f79 100644 --- a/src/main/java/lambdasinaction/chap11/v1/Shop.java +++ b/src/main/java/lambdasinaction/chap11/v1/Shop.java @@ -26,12 +26,12 @@ private double calculatePrice(String product) { } public Future getPriceAsync(String product) { - CompletableFuture futurePrice = new CompletableFuture<>(); + CompletableFuture futurePrice = new CompletableFuture<>();//创建CompletableFuture对象,它会包含计算的结果 new Thread( () -> { - double price = calculatePrice(product); - futurePrice.complete(price); + double price = calculatePrice(product);//在另一个线程中以异步的形式执行计算 + futurePrice.complete(price);//需要长时间计算的任务结束并得出结果时,设置Future返回值 }).start(); - return futurePrice; + return futurePrice;//无需等待还没结束的计算,志杰返回Future对象 } public String getName() { diff --git a/src/main/java/lambdasinaction/chap11/v1/ShopMain.java b/src/main/java/lambdasinaction/chap11/v1/ShopMain.java index ea1a19c1..f6e9f559 100644 --- a/src/main/java/lambdasinaction/chap11/v1/ShopMain.java +++ b/src/main/java/lambdasinaction/chap11/v1/ShopMain.java @@ -8,7 +8,7 @@ public class ShopMain { public static void main(String[] args) { Shop shop = new Shop("BestShop"); long start = System.nanoTime(); - Future futurePrice = shop.getPriceAsync("my favorite product"); + Future futurePrice = shop.getPriceAsync("my favorite product");//查询商品,试图取得商品的价格 long invocationTime = ((System.nanoTime() - start) / 1_000_000); System.out.println("Invocation returned after " + invocationTime + " msecs"); @@ -16,7 +16,7 @@ public static void main(String[] args) { doSomethingElse(); // while the price of the product is being calculated try { - double price = futurePrice.get(); + double price = futurePrice.get();//从future对象中都区价格,如果价格未知,会发生阻塞 System.out.printf("Price is %.2f%n", price); } catch (ExecutionException | InterruptedException e) { throw new RuntimeException(e); diff --git a/src/main/java/lambdasinaction/chap7/WordCount.java b/src/main/java/lambdasinaction/chap7/WordCount.java index 13ccce52..3717053e 100644 --- a/src/main/java/lambdasinaction/chap7/WordCount.java +++ b/src/main/java/lambdasinaction/chap7/WordCount.java @@ -55,16 +55,16 @@ public WordCounter(int counter, boolean lastSpace) { this.lastSpace = lastSpace; } - public WordCounter accumulate(Character c) { + public WordCounter accumulate(Character c) {//遍历Character if (Character.isWhitespace(c)) { return lastSpace ? this : new WordCounter(counter, true); } else { - return lastSpace ? new WordCounter(counter+1, false) : this; + return lastSpace ? new WordCounter(counter+1, false) : this;//上一个字符为空格,本字符不是空格时计数器加一 } } public WordCounter combine(WordCounter wordCounter) { - return new WordCounter(counter + wordCounter.counter, wordCounter.lastSpace); + return new WordCounter(counter + wordCounter.counter, wordCounter.lastSpace);//仅需要计数器的总和,无需关心lastSpace } public int getCounter() { @@ -83,20 +83,20 @@ private WordCounterSpliterator(String string) { @Override public boolean tryAdvance(Consumer action) { - action.accept(string.charAt(currentChar++)); - return currentChar < string.length(); + action.accept(string.charAt(currentChar++));//处理当前字符串 + return currentChar < string.length();//如果还有字符串要处理,则返回true } @Override public Spliterator trySplit() { int currentSize = string.length() - currentChar; if (currentSize < 10) { - return null; + return null;//返回null表示要解析的string足够小,可以顺序处理 } - for (int splitPos = currentSize / 2 + currentChar; splitPos < string.length(); splitPos++) { - if (Character.isWhitespace(string.charAt(splitPos))) { - Spliterator spliterator = new WordCounterSpliterator(string.substring(currentChar, splitPos)); - currentChar = splitPos; + for (int splitPos = currentSize / 2 + currentChar; splitPos < string.length(); splitPos++) {//将试探拆分位置设定为要解析的string中间 + if (Character.isWhitespace(string.charAt(splitPos))) {//将拆分未知前进到下一个空格 + Spliterator spliterator = new WordCounterSpliterator(string.substring(currentChar, splitPos));//传建一个新的WordCounterSpliterator来解析string从开始到拆分位置的部分 + currentChar = splitPos;//将这个WordCounterSpliterator的起始位置设为拆分位置 return spliterator; } } From 8257ac1362ae2f85700029a4f09f68058163fcb6 Mon Sep 17 00:00:00 2001 From: yecllsl Date: Thu, 28 Sep 2017 16:11:04 +0800 Subject: [PATCH 4/6] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lambdasinaction/chap11/AsyncShop.java | 4 ++-- .../java/lambdasinaction/chap11/BestPriceFinder.java | 2 +- src/main/java/lambdasinaction/chap11/Discount.java | 2 +- src/main/java/lambdasinaction/chap11/Util.java | 2 +- .../lambdasinaction/chap11/v1/BestPriceFinder.java | 10 +++++----- .../lambdasinaction/chap11/v1/BestPriceFinderMain.java | 4 ++-- src/main/java/lambdasinaction/chap11/v1/Shop.java | 8 ++++---- src/main/java/lambdasinaction/chap11/v1/ShopMain.java | 4 ++-- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/main/java/lambdasinaction/chap11/AsyncShop.java b/src/main/java/lambdasinaction/chap11/AsyncShop.java index 9d537368..b929d9d2 100644 --- a/src/main/java/lambdasinaction/chap11/AsyncShop.java +++ b/src/main/java/lambdasinaction/chap11/AsyncShop.java @@ -23,9 +23,9 @@ public Future getPrice(String product) { new Thread( () -> { try { double price = calculatePrice(product); - futurePrice.complete(price); + futurePrice.complete(price);//价格计算正常结束,完成Future操作并设置价格 } catch (Exception ex) { - futurePrice.completeExceptionally(ex); + futurePrice.completeExceptionally(ex);//跑出导致失败的异常,完成这次Future的操作。 } }).start(); return futurePrice; diff --git a/src/main/java/lambdasinaction/chap11/BestPriceFinder.java b/src/main/java/lambdasinaction/chap11/BestPriceFinder.java index 51412e93..d2e402ee 100644 --- a/src/main/java/lambdasinaction/chap11/BestPriceFinder.java +++ b/src/main/java/lambdasinaction/chap11/BestPriceFinder.java @@ -21,7 +21,7 @@ public class BestPriceFinder { @Override public Thread newThread(Runnable r) { Thread t = new Thread(r); - t.setDaemon(true); + t.setDaemon(true);//使用守护线程——这种方式不会阻止程序的关停 return t; } }); diff --git a/src/main/java/lambdasinaction/chap11/Discount.java b/src/main/java/lambdasinaction/chap11/Discount.java index 5624abd1..896721dd 100644 --- a/src/main/java/lambdasinaction/chap11/Discount.java +++ b/src/main/java/lambdasinaction/chap11/Discount.java @@ -4,7 +4,7 @@ import static lambdasinaction.chap11.Util.format; public class Discount { - + //枚举定义的折扣代码 public enum Code { NONE(0), SILVER(5), GOLD(10), PLATINUM(15), DIAMOND(20); diff --git a/src/main/java/lambdasinaction/chap11/Util.java b/src/main/java/lambdasinaction/chap11/Util.java index a72c4d33..2040c1e8 100644 --- a/src/main/java/lambdasinaction/chap11/Util.java +++ b/src/main/java/lambdasinaction/chap11/Util.java @@ -13,7 +13,7 @@ public class Util { private static final Random RANDOM = new Random(0); private static final DecimalFormat formatter = new DecimalFormat("#.##", new DecimalFormatSymbols(Locale.US)); - public static void delay() { + public static void delay() {//静态方法实现延时功能 int delay = 1000; //int delay = 500 + RANDOM.nextInt(2000); try { diff --git a/src/main/java/lambdasinaction/chap11/v1/BestPriceFinder.java b/src/main/java/lambdasinaction/chap11/v1/BestPriceFinder.java index 1bbb6030..98d89a97 100644 --- a/src/main/java/lambdasinaction/chap11/v1/BestPriceFinder.java +++ b/src/main/java/lambdasinaction/chap11/v1/BestPriceFinder.java @@ -33,29 +33,29 @@ public Thread newThread(Runnable r) { return t; } }); - + //通过stream方式获取价格 public List findPricesSequential(String product) { return shops.stream() .map(shop -> shop.getName() + " price is " + shop.getPrice(product)) .collect(Collectors.toList()); } - + //并行流的方式处理list public List findPricesParallel(String product) { return shops.parallelStream() .map(shop -> shop.getName() + " price is " + shop.getPrice(product)) .collect(Collectors.toList()); } - + //使用两个Stream并行的处理两个队列的数据。 public List findPricesFuture(String product) { List> priceFutures = shops.stream() .map(shop -> CompletableFuture.supplyAsync(() -> shop.getName() + " price is " + shop.getPrice(product), executor)) - .collect(Collectors.toList()); + .collect(Collectors.toList());//使用CompletableFuture以异步的方式计算每种商品的价格。 List prices = priceFutures.stream() .map(CompletableFuture::join) - .collect(Collectors.toList()); + .collect(Collectors.toList());//等待所有异步操作结束。 return prices; } diff --git a/src/main/java/lambdasinaction/chap11/v1/BestPriceFinderMain.java b/src/main/java/lambdasinaction/chap11/v1/BestPriceFinderMain.java index 5a74161a..2252c698 100644 --- a/src/main/java/lambdasinaction/chap11/v1/BestPriceFinderMain.java +++ b/src/main/java/lambdasinaction/chap11/v1/BestPriceFinderMain.java @@ -8,8 +8,8 @@ public class BestPriceFinderMain { private static BestPriceFinder bestPriceFinder = new BestPriceFinder(); public static void main(String[] args) { - execute("sequential", () -> bestPriceFinder.findPricesSequential("myPhone27S")); - execute("parallel", () -> bestPriceFinder.findPricesParallel("myPhone27S")); + execute("sequential", () -> bestPriceFinder.findPricesSequential("myPhone27S"));//4S多的处理时间 + execute("parallel", () -> bestPriceFinder.findPricesParallel("myPhone27S"));//并行处理后1S多的处理时间 execute("composed CompletableFuture", () -> bestPriceFinder.findPricesFuture("myPhone27S")); execute("combined USD CompletableFuture", () -> bestPriceFinder.findPricesInUSD("myPhone27S")); execute("combined USD CompletableFuture v2", () -> bestPriceFinder.findPricesInUSD2("myPhone27S")); diff --git a/src/main/java/lambdasinaction/chap11/v1/Shop.java b/src/main/java/lambdasinaction/chap11/v1/Shop.java index af557f79..4daa6da7 100644 --- a/src/main/java/lambdasinaction/chap11/v1/Shop.java +++ b/src/main/java/lambdasinaction/chap11/v1/Shop.java @@ -24,14 +24,14 @@ private double calculatePrice(String product) { delay(); return random.nextDouble() * product.charAt(0) + product.charAt(1); } - - public Future getPriceAsync(String product) { + //异步方法的实现,后续异步客户端的调用 + public Future getPriceAsync(String product) {//将上面的getPrice同步方法变成异步方法 CompletableFuture futurePrice = new CompletableFuture<>();//创建CompletableFuture对象,它会包含计算的结果 - new Thread( () -> { + new Thread( () -> {//新的线程中 double price = calculatePrice(product);//在另一个线程中以异步的形式执行计算 futurePrice.complete(price);//需要长时间计算的任务结束并得出结果时,设置Future返回值 }).start(); - return futurePrice;//无需等待还没结束的计算,志杰返回Future对象 + return futurePrice;//无需等待还没结束的计算,直接返回Future对象 } public String getName() { diff --git a/src/main/java/lambdasinaction/chap11/v1/ShopMain.java b/src/main/java/lambdasinaction/chap11/v1/ShopMain.java index f6e9f559..e072e0d9 100644 --- a/src/main/java/lambdasinaction/chap11/v1/ShopMain.java +++ b/src/main/java/lambdasinaction/chap11/v1/ShopMain.java @@ -12,11 +12,11 @@ public static void main(String[] args) { long invocationTime = ((System.nanoTime() - start) / 1_000_000); System.out.println("Invocation returned after " + invocationTime + " msecs"); - // Do some more tasks, like querying other shops + // Do some more tasks, like querying other shops返回之前可以做其他事情,不阻塞当前线程 doSomethingElse(); // while the price of the product is being calculated try { - double price = futurePrice.get();//从future对象中都区价格,如果价格未知,会发生阻塞 + double price = futurePrice.get();//从future对象中都区价格,如果价格未知,会发生阻塞。这个方法不能用于实际生产,不能靠时间要靠状态(事件)驱动 System.out.printf("Price is %.2f%n", price); } catch (ExecutionException | InterruptedException e) { throw new RuntimeException(e); From 5ad46162b8bc10e5736033b24ad8eb5bb16617c5 Mon Sep 17 00:00:00 2001 From: yecllsl Date: Mon, 13 Nov 2017 16:26:23 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E5=AF=B9=E4=BB=A3=E7=A0=81=E8=BF=9B?= =?UTF-8?q?=E8=A1=8C=E4=BA=86=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lambdasinaction/chap10/Car.java | 2 +- .../java/lambdasinaction/chap10/Insurance.java | 2 +- src/main/java/lambdasinaction/chap10/Person.java | 2 +- .../lambdasinaction/chap11/BestPriceFinder.java | 14 +++++++------- src/main/java/lambdasinaction/chap11/Discount.java | 3 ++- .../lambdasinaction/chap11/v1/BestPriceFinder.java | 10 +++++----- 6 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/main/java/lambdasinaction/chap10/Car.java b/src/main/java/lambdasinaction/chap10/Car.java index 36f00727..81417ed7 100644 --- a/src/main/java/lambdasinaction/chap10/Car.java +++ b/src/main/java/lambdasinaction/chap10/Car.java @@ -3,7 +3,7 @@ import java.util.*; public class Car { - + //车·可能有保险也可能没有保险,因此这个字段声明为optional private Optional insurance; public Optional getInsurance() { diff --git a/src/main/java/lambdasinaction/chap10/Insurance.java b/src/main/java/lambdasinaction/chap10/Insurance.java index 69409686..09394513 100644 --- a/src/main/java/lambdasinaction/chap10/Insurance.java +++ b/src/main/java/lambdasinaction/chap10/Insurance.java @@ -2,7 +2,7 @@ public class Insurance { - private String name; + private String name;//保险公司必须有名字,所以不用声明为optional public String getName() { return name; diff --git a/src/main/java/lambdasinaction/chap10/Person.java b/src/main/java/lambdasinaction/chap10/Person.java index 5e84e552..4ae691f6 100644 --- a/src/main/java/lambdasinaction/chap10/Person.java +++ b/src/main/java/lambdasinaction/chap10/Person.java @@ -3,7 +3,7 @@ import java.util.*; public class Person { - + //人可能有车也可能没有车,因此这个字段声明为optional private Optional car; public Optional getCar() { diff --git a/src/main/java/lambdasinaction/chap11/BestPriceFinder.java b/src/main/java/lambdasinaction/chap11/BestPriceFinder.java index d2e402ee..e685428f 100644 --- a/src/main/java/lambdasinaction/chap11/BestPriceFinder.java +++ b/src/main/java/lambdasinaction/chap11/BestPriceFinder.java @@ -28,9 +28,9 @@ public Thread newThread(Runnable r) { public List findPricesSequential(String product) { return shops.stream() - .map(shop -> shop.getPrice(product)) - .map(Quote::parse) - .map(Discount::applyDiscount) + .map(shop -> shop.getPrice(product))//获得每个shop对象中商品的原始价格 + .map(Quote::parse)//队返回字符串进行转换 + .map(Discount::applyDiscount)//联系Discount服务,为每个Quote申请折扣 .collect(Collectors.toList()); } @@ -53,15 +53,15 @@ public List findPricesFuture(String product) { public Stream> findPricesStream(String product) { return shops.stream() - .map(shop -> CompletableFuture.supplyAsync(() -> shop.getPrice(product), executor)) - .map(future -> future.thenApply(Quote::parse)) - .map(future -> future.thenCompose(quote -> CompletableFuture.supplyAsync(() -> Discount.applyDiscount(quote), executor))); + .map(shop -> CompletableFuture.supplyAsync(() -> shop.getPrice(product), executor))//以异步的方式获得每个shop对象中商品的原始价格 + .map(future -> future.thenApply(Quote::parse))//同步即可解决,同步的时候主线程和任务执行线程是同一个线程 + .map(future -> future.thenCompose(quote -> CompletableFuture.supplyAsync(() -> Discount.applyDiscount(quote), executor)));//使用另一个异步任务构造期望的future,申请折扣。theCompose方法,把两个Future连接起来 } public void printPricesStream(String product) { long start = System.nanoTime(); CompletableFuture[] futures = findPricesStream(product) - .map(f -> f.thenAccept(s -> System.out.println(s + " (done in " + ((System.nanoTime() - start) / 1_000_000) + " msecs)"))) + .map(f -> f.thenAccept(s -> System.out.println(s + " (done in " + ((System.nanoTime() - start) / 1_000_000) + " msecs)")))//通过thenAccept响应completion事件 .toArray(size -> new CompletableFuture[size]); CompletableFuture.allOf(futures).join(); System.out.println("All shops have now responded in " + ((System.nanoTime() - start) / 1_000_000) + " msecs"); diff --git a/src/main/java/lambdasinaction/chap11/Discount.java b/src/main/java/lambdasinaction/chap11/Discount.java index 896721dd..8567aea7 100644 --- a/src/main/java/lambdasinaction/chap11/Discount.java +++ b/src/main/java/lambdasinaction/chap11/Discount.java @@ -16,10 +16,11 @@ public enum Code { } public static String applyDiscount(Quote quote) { + //将折扣代码应用于商品最初的原始价格 return quote.getShopName() + " price is " + Discount.apply(quote.getPrice(), quote.getDiscountCode()); } private static double apply(double price, Code code) { - delay(); + delay();//模拟服务延迟 return format(price * (100 - code.percentage) / 100); } } diff --git a/src/main/java/lambdasinaction/chap11/v1/BestPriceFinder.java b/src/main/java/lambdasinaction/chap11/v1/BestPriceFinder.java index 98d89a97..e8ce4f74 100644 --- a/src/main/java/lambdasinaction/chap11/v1/BestPriceFinder.java +++ b/src/main/java/lambdasinaction/chap11/v1/BestPriceFinder.java @@ -50,11 +50,11 @@ public List findPricesFuture(String product) { List> priceFutures = shops.stream() .map(shop -> CompletableFuture.supplyAsync(() -> shop.getName() + " price is " - + shop.getPrice(product), executor)) + + shop.getPrice(product), executor))//以异步的方式取得每个shop中指定产品的原始价格 .collect(Collectors.toList());//使用CompletableFuture以异步的方式计算每种商品的价格。 List prices = priceFutures.stream() - .map(CompletableFuture::join) + .map(CompletableFuture::join)//等待流中的所有future执行完毕,并提取各自的返回值 .collect(Collectors.toList());//等待所有异步操作结束。 return prices; } @@ -67,10 +67,10 @@ public List findPricesInUSD(String product) { // CompletableFuture so that it is compatible with the // CompletableFuture::join operation below. CompletableFuture futurePriceInUSD = - CompletableFuture.supplyAsync(() -> shop.getPrice(product)) - .thenCombine( + CompletableFuture.supplyAsync(() -> shop.getPrice(product))//第一个任务查询商店取得商品的价格 + .thenCombine(//这个方法链接两个Future任务,如果调用Async的方法,两个任务在不同的线程中执行 CompletableFuture.supplyAsync( - () -> ExchangeService.getRate(Money.EUR, Money.USD)), + () -> ExchangeService.getRate(Money.EUR, Money.USD)),//创建第二个独立任务,查询美元和欧元之间的转换汇率 (price, rate) -> price * rate ); priceFutures.add(futurePriceInUSD); From 260af7144e431cc09fbdde9f412451f16bfebc32 Mon Sep 17 00:00:00 2001 From: yecllsl Date: Thu, 16 Nov 2017 11:12:33 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E7=BB=A7=E7=BB=AD=E8=AF=BB=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=EF=BC=8C=E5=8A=A0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/lambdasinaction/chap10/OptionalMain.java | 2 +- .../lambdasinaction/chap8/ChainOfResponsibilityMain.java | 2 +- src/main/java/lambdasinaction/chap8/FactoryMain.java | 2 +- src/main/java/lambdasinaction/chap8/ObserverMain.java | 2 +- src/main/java/lambdasinaction/chap8/Peek.java | 8 ++++---- src/main/java/lambdasinaction/chap8/StrategyMain.java | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/lambdasinaction/chap10/OptionalMain.java b/src/main/java/lambdasinaction/chap10/OptionalMain.java index 1826cb4a..9878f596 100644 --- a/src/main/java/lambdasinaction/chap10/OptionalMain.java +++ b/src/main/java/lambdasinaction/chap10/OptionalMain.java @@ -8,6 +8,6 @@ public String getCarInsuranceName(Optional person) { return person.flatMap(Person::getCar) .flatMap(Car::getInsurance) .map(Insurance::getName) - .orElse("Unknown"); + .orElse("Unknown");//如果optional的结果值为空,设置默认值 } } diff --git a/src/main/java/lambdasinaction/chap8/ChainOfResponsibilityMain.java b/src/main/java/lambdasinaction/chap8/ChainOfResponsibilityMain.java index 91d52e0a..e89c1767 100644 --- a/src/main/java/lambdasinaction/chap8/ChainOfResponsibilityMain.java +++ b/src/main/java/lambdasinaction/chap8/ChainOfResponsibilityMain.java @@ -13,7 +13,7 @@ public static void main(String[] args) { String result1 = p1.handle("Aren't labdas really sexy?!!"); System.out.println(result1); - + //通过lambda实现责任链模式 UnaryOperator headerProcessing = (String text) -> "From Raoul, Mario and Alan: " + text; UnaryOperator spellCheckerProcessing = diff --git a/src/main/java/lambdasinaction/chap8/FactoryMain.java b/src/main/java/lambdasinaction/chap8/FactoryMain.java index e30d219e..72d35e3b 100644 --- a/src/main/java/lambdasinaction/chap8/FactoryMain.java +++ b/src/main/java/lambdasinaction/chap8/FactoryMain.java @@ -26,7 +26,7 @@ public static Product createProduct(String name){ default: throw new RuntimeException("No such product " + name); } } - + //并不完美,不能完全替代现有的设计模式。尤其是带参数的情况 public static Product createProductLambda(String name){ Supplier p = map.get(name); if(p != null) return p.get(); diff --git a/src/main/java/lambdasinaction/chap8/ObserverMain.java b/src/main/java/lambdasinaction/chap8/ObserverMain.java index dcd8cb50..ac7d93ac 100644 --- a/src/main/java/lambdasinaction/chap8/ObserverMain.java +++ b/src/main/java/lambdasinaction/chap8/ObserverMain.java @@ -13,7 +13,7 @@ public static void main(String[] args) { f.registerObserver(new LeMonde()); f.notifyObservers("The queen said her favourite book is Java 8 in Action!"); - + //Lambda的实现方式 Feed feedLambda = new Feed(); feedLambda.registerObserver((String tweet) -> { diff --git a/src/main/java/lambdasinaction/chap8/Peek.java b/src/main/java/lambdasinaction/chap8/Peek.java index e25d68a4..281074cf 100644 --- a/src/main/java/lambdasinaction/chap8/Peek.java +++ b/src/main/java/lambdasinaction/chap8/Peek.java @@ -11,9 +11,9 @@ public class Peek { public static void main(String[] args) { List result = Stream.of(2, 3, 4, 5) - .peek(x -> System.out.println("taking from stream: " + x)).map(x -> x + 17) - .peek(x -> System.out.println("after map: " + x)).filter(x -> x % 2 == 0) - .peek(x -> System.out.println("after filter: " + x)).limit(3) - .peek(x -> System.out.println("after limit: " + x)).collect(toList()); + .peek(x -> System.out.println("taking from stream: " + x)).map(x -> x + 17)//输出来自数据源的当前元素值 + .peek(x -> System.out.println("after map: " + x)).filter(x -> x % 2 == 0)//输出map操作结果 + .peek(x -> System.out.println("after filter: " + x)).limit(3)//输出经过filter操作之后,剩下的元素个数 + .peek(x -> System.out.println("after limit: " + x)).collect(toList());//输出经过limit操作之后,剩下的元素个数 } } diff --git a/src/main/java/lambdasinaction/chap8/StrategyMain.java b/src/main/java/lambdasinaction/chap8/StrategyMain.java index cc899aa8..2ce2850c 100644 --- a/src/main/java/lambdasinaction/chap8/StrategyMain.java +++ b/src/main/java/lambdasinaction/chap8/StrategyMain.java @@ -11,7 +11,7 @@ public static void main(String[] args) { System.out.println(v2.validate("bbbb")); - // with lambdas + // with lambdas 新的利用lambdas的策略方式 Validator v3 = new Validator((String s) -> s.matches("\\d+")); System.out.println(v3.validate("aaaa")); Validator v4 = new Validator((String s) -> s.matches("[a-z]+"));