JUC学习的第二天

JUC第二天总结

get 和 join的区别

get和join一样的都会造成线程堵塞,区别就是join不抛出异常。
使用get需要抛异常
使用join不需要抛异常

CompletableFutrue的应用

public class CompletableFutureDemo01 {
    /**CompletableFuture应用
     * 需求:
     *  同一款产品,同时搜索出同款产品在不同平台的售价
     *  同一款产品,同时搜索出同款产品在同一个平台的各个商家的售价
     * 技术:
     *  stream流式计算,函数式编程,链式编程
     */
    //定义一个静态数组
    static List<Product> list = Arrays.asList(
            new Product("pdd"),
            new Product("taobao"),
            new Product("tmall"),
            new Product("jd")
    );

    //同步 step by step
    public static List<String> productStep(List<Product> list ,String productPriceName){

        return list.stream()
                .map(product ->  String.format(productPriceName+" in %s price is %.2f",
                        product.getProductName(),product.getProductPrice(productPriceName)))
                .collect(Collectors.toList());
    }
    //异步 万剑齐发
    public static List<String> productAsynt(List<Product> list ,String productPriceName){
      return  list.stream()
                .map(product -> CompletableFuture.supplyAsync(() ->
                        String.format(productPriceName+" in %s price is %.2f",product.getProductName()
                                ,product.getProductPrice(productPriceName))))
                .collect(Collectors.toList())
              .stream()
              .map(CompletableFuture::join)
              .collect(Collectors.toList());
    }


    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        List<String> list = productStep(CompletableFutureDemo01.list, "mysql");
        for (String s : list) {
            System.out.println(s);
        }
        long endTime = System.currentTimeMillis();

        System.out.println("耗时:"+(endTime - startTime)+"s");
        long startTime1 = System.currentTimeMillis();
        List<String> list1 = productAsynt(CompletableFutureDemo01.list, "mysql");
        for (String s : list1) {
            System.out.println(s);
        }
        long endTime1 = System.currentTimeMillis();
        System.out.println("耗时:"+(endTime1 - startTime1)+"s");
    }
}
class Product{
    @Getter
    private String productName;

    public Product(String productName) {
        this.productName = productName;
    }

    public double getProductPrice(String productPriceName){
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return ThreadLocalRandom.current().nextDouble()*2 + productPriceName.charAt(0);
    }
}

运行结果:

mysql in pdd price is 110.24
mysql in taobao price is 110.18
mysql in tmall price is 109.90
mysql in jd price is 110.74
耗时:4173s
mysql in pdd price is 109.79
mysql in taobao price is 109.35
mysql in tmall price is 109.43
mysql in jd price is 110.92
耗时:1022s

由此看出同步与异步执行结果的差别了吧。

CompletableFuture常用方法

获取结果和触发计算

获取结果:
==public T get() ==:不见不散
不管让程序休眠多长时间,只要返回我就接受

 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 20, 1L,
                TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(50), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
        CompletableFuture<Integer> exceptionally = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 147;
        });
        System.out.println(exceptionally.get());
//        TimeUnit.SECONDS.sleep(5);
        threadPoolExecutor.shutdown();

==public T get(long timeout, TimeUnit unit) ==:过时不候
设置一个等待时间要是在规定时间类获取到值,则输出

 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 20, 1L,
                TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(50), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
        CompletableFuture<Integer> exceptionally = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 147;
        });
        System.out.println(exceptionally.get(2,TimeUnit.SECONDS));
//        TimeUnit.SECONDS.sleep(5);
        threadPoolExecutor.shutdown();

public T getNow(T valueIfAbsent):没有计算完成的情况下给我一个替代结果,也就是立即获取结果不阻塞,计算完返回计算完成后的结果,没有计算完则返回valueIfAbsent的值

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 20, 1L,
                TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(50), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
        CompletableFuture<Integer> exceptionally = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 147;
        });
        //TimeUnit.SECONDS.sleep(2);
        System.out.println(exceptionally.getNow(520));
        threadPoolExecutor.shutdown();

public T join()

 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 20, 1L,
                TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(50), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
        System.out.println(CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 147;
        }).join());
        //TimeUnit.SECONDS.sleep(2);
        threadPoolExecutor.shutdown();

==public boolean complete(T value) ==:是否立即打断get()返回括号值

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 20, 1L,
                TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(50), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
        CompletableFuture<Integer> exceptionally = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 147;
        });

//当调用CompletableFuture.get()被阻塞的时候,complete方法就是结束阻塞并get()获取设置的complete里面的值.
        System.out.println(exceptionally.complete(520) + "\t" + exceptionally.get());
        threadPoolExecutor.shutdown()
对结算结果进行处理

thenApply:
计算结果存在依赖关系,这两个线程串行化;由于存在依赖关系(当前步错,不走下一步),当前步骤有异常的话就叫停。


//当一个线程依赖另一个线程时用 thenApply 方法来把这两个线程串行化,
CompletableFuture.supplyAsync(() -> {
//暂停几秒钟线程
try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
        System.out.println("111");
return 1024;
    }).thenApply(f -> {
        System.out.println("222");
return f + 1;
    }).thenApply(f -> {
//int age = 10/0; // 异常情况:那步出错就停在那步。
System.out.println("333");
return f + 1;
    }).whenCompleteAsync((v,e) -> {
        System.out.println("*****v: "+v);
    }).exceptionally(e -> {
        e.printStackTrace();
return null;
    });

    System.out.println("-----主线程结束,END");

// 主线程不要立刻结束,否则CompletableFuture默认使用的线程池会立刻关闭:
try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); }
}

handle:有异常也可以往下一步走,根据带的异常参数可以进一步处理


//当一个线程依赖另一个线程时用 handle 方法来把这两个线程串行化,
        // 异常情况:有异常也可以往下一步走,根据带的异常参数可以进一步处理
CompletableFuture.supplyAsync(() -> {
//暂停几秒钟线程
try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
            System.out.println("111");
return 1024;
        }).handle((f,e) -> {
int age = 10/0;
            System.out.println("222");
return f + 1;
        }).handle((f,e) -> {
            System.out.println("333");
return f + 1;
        }).whenCompleteAsync((v,e) -> {
            System.out.println("*****v: "+v);
        }).exceptionally(e -> {
            e.printStackTrace();
return null;
        });

        System.out.println("-----主线程结束,END");

// 主线程不要立刻结束,否则CompletableFuture默认使用的线程池会立刻关闭:
try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); }
    }

whencomplete和whencompleteAsync的区别
whencomplete:是执行当前任务的线程执行继续执行whencomplete的任务
whencompleteAsync:是执行把whencompleteAsync这个任务继续提交给线程池来进行执行

对计算结果进行消费

thenApply

  CompletableFuture.supplyAsync(() -> {
return 1;
    }).thenApply(f -> {
return f + 2;
    }).thenApply(f -> {
return f + 3;
    }).thenApply(f -> {
return f + 4;
    }).thenAccept(r -> System.out.println(r));

补充 :Code之任务之间的顺序执行
thenRun(Runnable runnable)
任务 A 执行完执行 B,并且 B 不需要 A 的结果
thenAccept(Consumer action)
任务 A 执行完执行 B,B 需要 A 的结果,但是任务 B 无返回值
thenApply(Function fn)
任务 A 执行完执行 B,B 需要 A 的结果,同时任务 B 有返回值

对计算速度进行选用

applyToEither
谁快用谁

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 20, 1L,
                TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(50), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());


        System.out.println(CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 1;
        }).applyToEither(CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 2;
        }), r -> {
            return r;
        }).join());

        TimeUnit.SECONDS.sleep(3);
        threadPoolExecutor.shutdown();
对计算结果进行合并

thenCombine
两个CompletionStage任务都完成后,最终能把两个任务的结果一起交给thenCombine 来处理

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 20, 1L,
                TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(50), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());

        
        System.out.println(CompletableFuture.supplyAsync(() -> {
            return 10;
        }).thenCombine(CompletableFuture.supplyAsync(() ->{
            return 12;
        }),(r1,r2) ->{
            return r1+r2;
        }).thenCombine(CompletableFuture.supplyAsync(() ->{
            return 20;
        }),(r1,r2) ->{
            return r1+r2;
        }).join());

        TimeUnit.SECONDS.sleep(3);
        threadPoolExecutor.shutdown();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值