文章目录
- 1 Future接口
- 1.1 FutureTask相关接口关系
- 1.2 Future接口的优缺点
- 1.2.1 优点
- 1.2.2 缺点
- 2 Complatable Future
- 2.1 CompletionStage
- 2.2 使用案例
- 2.2.1 runAsync
- 2.2.2 supplyAsync
- 2.2.3 join和get的区别
- 2.2.4 CF simple project使用案例
- 2.2.5 CF 常用API
- 2.2.5.1 获取结果和主动触发计算
- 2.2.5.2 对计算结果进行处理
- 2.2.5.3 对计算结果进行消费
- 2.2.5.4 对计算速度进行选用
1 Future接口
1.1 FutureTask相关接口关系
1.2 Future接口的优缺点
1.2.1 优点
结合线程池,可以提升程序的运算效率。
1.2.2 缺点
(1) get方法阻塞
(2)isDone通常会轮询
我们还想需要:
(1) 缺少完成时的回调通知。
(2) 多个任务前后依赖可以组合处理。
(3)选择计算速度最快的那个线程。
2 Complatable Future
2.1 CompletionStage
2.2 使用案例
2.2.1 runAsync
2.2.2 supplyAsync
package org.example.completablefuturetest;import java.util.concurrent.*;public class CompletableFutureUseDemo {public static void main(String[] args) {ExecutorService threadPool = Executors.newFixedThreadPool(3);try {CompletableFuture.supplyAsync(() -> {System.out.println(Thread.currentThread().getName() + "-------come in.");int result = ThreadLocalRandom.current().nextInt(10);try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("---------2s之后出结果---" + result);if (result > 2) {throw new RuntimeException("sk, throw a run time exception.");}return result;}, threadPool).whenComplete((value, exception) -> {if (exception == null) {System.out.println("-------计算完成,更新系统value:---" + value);}}).exceptionally(exception -> {System.out.println("sk, will handle a ex.");exception.printStackTrace();return null;});System.out.println(Thread.currentThread().getName() + "线程先去忙其他任务");} catch (Exception exception) {exception.printStackTrace();} finally {threadPool.shutdown();}}
}
2.2.3 join和get的区别
就是抛出的异常不一样。 join不需要使用方显示地捕获异常。
public class CompletableFutureMallDemo {public static void main(String[] args) {CompletableFuture cf = CompletableFuture.supplyAsync(new Supplier<String>() {@Overridepublic String get() {return "sk, 1234";}});System.out.println(cf.join());}
}
2.2.4 CF simple project使用案例
package org.example.cfmall;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import java.util.stream.Collectors;public class CompletableFutureMallDemo {static List<NetMall> list = Arrays.asList(new NetMall("jingdong"),new NetMall("dangdang"),new NetMall("taobao"));public static List<String> getPrice(List<NetMall> list, String productName) {// return getPriceStepByStep(list, productName);return getPriceAsync(list, productName);}private static List<String> getPriceAsync(List<NetMall> list, String productName) {return list.stream().map(netMall -> CompletableFuture.supplyAsync(new Supplier<String>() {@Overridepublic String get() {return String.format(productName + "in %s price is %.2f",netMall.getNetMallName(), netMall.calcPrice(productName));}})).collect(Collectors.toList()).stream().map(cf -> cf.join()).collect(Collectors.toList());}private static List<String> getPriceStepByStep(List<NetMall> list, String productName) {return list.stream().map(netMall -> String.format(productName + "in %s price is %.2f",netMall.getNetMallName(), netMall.calcPrice(productName))).collect(Collectors.toList());}public static void main(String[] args) {long startTime = System.currentTimeMillis();List<String> priceList = getPrice(list, "mysql");for (String price : priceList) {System.out.println(price);}long endTime = System.currentTimeMillis();System.out.println("------costTime: " + (endTime - startTime) + " ms");}
}@AllArgsConstructor
@NoArgsConstructor
@Data
class NetMall {private String netMallName;public double calcPrice(String productName) {try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}return ThreadLocalRandom.current().nextDouble() * 2 + productName.charAt(0);}
}
2.2.5 CF 常用API
2.2.5.1 获取结果和主动触发计算
2.2.5.2 对计算结果进行处理
2.2.5.3 对计算结果进行消费
带Async后缀和不带后缀的api的区别