企业级微服务架构实战项目--xx优选-详情页面的异步调用completablefuture

一  常见的调用方式

1.1 并发

并发:同一时刻多个线程在访问同一个资源,多个线程对一个点

​ 例子:春运抢票、微信抢红包、电商秒杀...

1.2 同步串行

代表多任务按先后顺序执行,并且都是同一个线程来执行。

1.3 异步串行

代表多任务按先后顺序执行,并由不同的线程来执行。

 

 1.4 并行

多项任务一起执行,之后再汇总

例子:泡方便面,电水壶烧水,一边撕调料倒入桶中

 1.5 任务合并

一个任务的执行依赖于前面多个任务执行的返回值,并且这些任务可以由同一个线程执行,也可以由不同的线程执行;

 1.6 多线程的4种范式

第一种 继承Thread类

第二种 实现Runnable接口

第三种 使用Callable接口

第四种 使用线程池

二  completableFuture实现

2.1 作用

CompletableFuture异步编排,CompletableFuture和FutureTask同属于Future接口的实现类,都可以获取线程的执行结果。

2.2  runAsync方法没有返回值

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Demo1 {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        System.out.println("main begin....");
        CompletableFuture<Void> completableFuture =
                CompletableFuture.runAsync(()->{
                    System.out.println("当前线程:"+Thread.currentThread().getId());
                    int result = 1024;
                    System.out.println("result:"+result);
                },executorService);
        System.out.println("main over....");
    }
}

2.3  supplyAsync 方法有返回值

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Demo2 {
    public static void main(String[] args) throws Exception {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        System.out.println("main begin....");
        CompletableFuture<Integer> completableFuture =
                CompletableFuture.supplyAsync(()->{
                    System.out.println("当前线程:"+Thread.currentThread().getId());
                    int result = 1024;
                    System.out.println("result:"+result);
                    return result;
                },executorService);
        //获取返回结果
        Integer value = completableFuture.get();
        System.out.println("main over...."+value);
    }
}

2.4 计算完成时回调方法

whenComplete可以处理正常或异常的计算结果,exceptionally处理异常情况。

whenComplete 和 whenCompleteAsync 的区别:

whenComplete:是执行当前任务的线程执行继续执行 whenComplete 的任务。

whenCompleteAsync:是执行把 whenCompleteAsync 这个任务继续提交给线程池来进行执行。

方法不以Async结尾,意味着Action使用相同的线程执行,而Async可能会使用其他线程执行(如果是使用相同的线程池,也可能会被同一个线程选中执行)

public class Demo3 {
    public static void main(String[] args) throws Exception {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        System.out.println("main begin....");
        CompletableFuture<Integer> completableFuture =
                CompletableFuture.supplyAsync(()->{
                    System.out.println("当前线程:"+Thread.currentThread().getId());
                    int result = 10/0;
                    System.out.println("result:"+result);
                    return result;
                },executorService)
                        .whenComplete((rs,exception)->{
                            System.out.println("结果:"+rs);
                            System.out.println(exception);
                        });
        System.out.println("main over....");
    }
}

2.5 线程串行化方法

1.thenApply 方法:当一个线程依赖另一个线程时,获取上一个任务返回的结果,并返回当前任务的返回值。

2.thenAccept方法:消费处理结果。接收任务的处理结果,并消费处理,无返回结果。

3henRun方法:只要上面的任务执行完成,就开始执行thenRun,只是处理完任务后,执行 thenRun的后续操作

带有Async默认是异步执行的。这里所谓的异步指的是不在当前线程内执行

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Demo4 {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        // 线程1执行返回的结果:100
        CompletableFuture<Integer> futureA =
                CompletableFuture.supplyAsync(() -> {
                    int res = 100;
                    System.out.println("线程一:"+res);
                    return res;
                });

        // 线程2 获取到线程1执行的结果
        CompletableFuture<Integer> futureB = futureA.thenApplyAsync((res)->{
            System.out.println("线程二--"+res);
            return ++res;
        },executorService);

        //线程3: 无法获取futureA返回结果
        CompletableFuture<Void> futureC = futureA.thenRunAsync(() -> {
            System.out.println("线程三....");
        }, executorService);
    }
}

2.6 多任务组合

allOf:等待所有任务完成

anyOf:只要有一个任务完成

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Demo5 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(4);
        // 线程1
        CompletableFuture<Integer> futureA =
                CompletableFuture.supplyAsync(() -> {
                    System.out.println(Thread.currentThread().getName()+"--begin..");
                    int res = 100;
                    System.out.println("一:"+res);
                    System.out.println(Thread.currentThread().getName()+"--over..");
                    return res;
                },executorService);

        // 线程2
        CompletableFuture<Integer> futureB =
                CompletableFuture.supplyAsync(() -> {
                    System.out.println(Thread.currentThread().getName()+"--begin..");
                    int res = 30;
                    System.out.println("二:"+res);
                    System.out.println(Thread.currentThread().getName()+"--over..");
                    return res;
                },executorService);

        CompletableFuture<Void> all = CompletableFuture.allOf(futureA,futureB);
        all.get();
        System.out.println("over....");
    }
}

三  实战completableFuture的异步调用

3.1 异步调用

1.自定义线程池

2.异步调用

 3.2 多模块微服务调用

3.2.1 product,activity,search模块

3.2.2 search模块

(1)实现功能:更新es 中 hotScore 值,这个值越大说明热度就越高

(2)热度指商品被用户查看的次数。用户每访问一次就更新一次 es 中的hotscore, es 中的数据存储在磁盘中,如果频繁更新会产生大量IO操作,因此使用redis 进行实现。商品每次被访问的时候,将这个访问量 在redis 中进行 +1 操作。当redis 中这个值 达到一定规则的时候,那么再去更新一次es。规则:hotScore%10==0

1.调用

2.客户端

 

3.调用search模块

 3.3 es的springboot-data-es的集成操作

 1.获取爆款产品

2.通过集成查询 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值