ForkJoinPool的介绍以及微服务并行调用多个外部接口

1、概念

1.1、用来做什么

在这里插入图片描述

1.2、意图梳理

在这里插入图片描述

1.3、使用场景

经典网关场景,查询多个系统数据,由于是接口调用,存在阻塞性,所以并不适合下边这种情况,但本教程会涉及到这个场景的实现来达到了解ForkJoinPool的使用,通过这个场景可以更清楚了解ForkJoinPool的使用:
在这里插入图片描述
通常的使用场景下边1.5会列出

1.4、实现思路

在这里插入图片描述

1.5、适用

在这里插入图片描述

2、代码

2.1、应用场景

一个方法中调用多个微服务获取数据:
在这里插入图片描述
上边这样写的问题是很大的,接口响应总时间大概为调用的各个微服务接口时间之和(还不包括本接口的其他逻辑处理),所以这样效率是非常低的。我们可以采用多线程应用来做这个事情。

先来了解forkjoinpool,它本质上还是一个线程池,默认的线程数量为cpu的核数,可以通过调用Executeors来获取,也可以直接用return 后边的代码进行创建:
在这里插入图片描述
forkjoinpool的使用方法与我们平时的线程池类似,也是用submit方法,不过除了可以穿runable和callable参数,多了可以传forkjointask参数的方法,由于这个类是一个抽象类,我们经常继承下边两个子抽象类做具体实现:
在这里插入图片描述

2.2、场景解决方法

前两个顺便提供了这个场景的常用方法,最后一个是为了介绍ForkJoinPool的使用才写的,实际中这样用到的并不多

2.2.1、利用FutureTask解决

这里顺便为了了解FutureTask的大致原理,自制了一个简单的futuretask,如不需要了解FutureTask原理可直接跳过:

import java.util.concurrent.*;
import java.util.concurrent.locks.LockSupport;

// 我们想一想,这个功能怎么实现
// (jdk本质,就是利用一些底层API,为开发人员提供便利)
public class NeteaseFutureTask<T> implements Runnable, Future {
    // 获取 线程异步执行结果 的方式
    Callable<T> callable; //  业务逻辑在callable里面
    T result = null;
    volatile String state = "NEW";  // task执行状态
    LinkedBlockingQueue<Thread> waiters = new LinkedBlockingQueue<>();// 定义一个存储等待者的集合

    public NeteaseFutureTask(Callable<T> callable) {
   
        this.callable = callable;
    }

    @Override
    public void run() {
   
        try {
   
            result = callable.call();
        } catch (Exception e) {
   
            e.printStackTrace();
            // result = exception
        } finally {
   
            state = "END";
        }

        // 唤醒等待者
        Thread waiter = waiters.poll();
        while (waiter != null) {
   
            LockSupport.unpark(waiter);

            waiter = waiters.poll(); // 继续取出队列中的等待者
        }
    }

    // 返回结果,
    @Override
    public T get() {
   
        if ("END".equals(state)) {
   
            return result;
        }

        waiters.offer(Thread.currentThread()); // 加入到等待队列,线程不继续往下执行

        while (!"END".equals(state)) {
   
            LockSupport.park(); // 线程通信的知识点
        }
        // 如果没有结束,那么调用get方法的线程,就应该进入等待
        return result;
    }

    @Override
    public boolean cancel(boolean mayInterruptIfRunning) {
   
        return false;
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jarbein

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值