join方法应用之—查询航班信息

本文介绍了如何使用Java实现航班查询功能,通过定义接口和任务实现类,模拟从多个航空公司接口获取航班信息的过程。在主线程中,创建并启动查询线程,使用join方法确保所有查询完成后再汇总结果。此示例展示了线程的串行任务局部并行处理,有助于理解多线程在实际问题中的应用。
摘要由CSDN通过智能技术生成

哈喽,小伙伴们,大家好。本章节继续分享join应用,希望大家有所收获。好了,废话不多说,进入正题。


需求:

假设一个软件,需要实现这样一个功能,主要用于查询航班信息,你的软件没有这些实时数据的,所以当用户发起查询请求时,你需要到各大航空公司的接口获取信息,最后统一整理加工返回到客户端。需求大概如下图:
在这里插入图片描述

分析:

其实功能很简单,就是我们输入起始地址,然后去查询每一家航空公司的航班信息,返回给我们,我们处理之后,再返回给客户端。就是先串行然后并行然后串行,即串行任务局部并行。
第一步:定义一个接口

/**
 * 航班查询
 */
public interface FlightQuery {

    List<String> get();// 航空公司名称-查询时长

}

因为不管是Thread 的 run 方法,还是 Runnable 接口,都是 void 返回类型,如果你想通过某个线程的运行得到结果,就需要自己定义一个返回接口。

第二步:定义一个任务实现类,去实现FlightQuery并且继承Thread类。

public class FlightQueryTask extends Thread implements FlightQuery {

    private final String origin;// 出发地
    private final String destination;// 目的地
    private final List<String> flightList = new ArrayList<>();// 航班信息集合

    public FlightQueryTask(String airline, String origin, String destination) {
        super("[" + airline + "]");// 使用航空公司名称为线程命名
        this.origin = origin;
        this.destination = destination;
    }

    @Override
    public void run() {
        // 航空公司查询从出发地到目的地
        System.out.printf("%s-query from %s to %s \n", this.getName(), origin, destination);
        // 随机生成随机数模拟查询时长
        int randomVal = ThreadLocalRandom.current().nextInt(10);
        try {
            TimeUnit.SECONDS.sleep(randomVal);
            // 将航空公司和查询时长添加至航班信息集合中
            this.flightList.add(this.getName() + "-" + randomVal);
            System.out.printf("The Flight:%s list query successful\n", this.getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public List<String> get() {
        return this.flightList;// 返回航班查询信息
    }

}

在代码里面,很多代码你可以不看,主要就是重执行单元run方法,因为逻辑都在run方法里面。然后run方法重点就是将航空公司和查询时长添加至航班信息集合中,最后通过get()方法获取航班信息。

第三步:编写具体实现类。


public class FlightQueryExample {

    // APP 合作的航空公司
    private static List<String> airlineList = Arrays.asList("南方航空", "东方航空", "海南航空");

    public static void main(String[] args) {
        List<String> results = search("SH", "BJ");
        System.out.println("----------result----------");
        results.forEach(System.out::println);
    }

    private static List<String> search(String origin, String destination) {
        final List<String> result = new ArrayList<>();// 聚合所有航空公司查询结果的集合
        // 创建查询航班信息的线程列表
        List<FlightQueryTask> tasks = airlineList.stream()
                .map(f -> new FlightQueryTask(f, origin, destination))
                .collect(Collectors.toList());
        // 启动线程
        tasks.forEach(Thread::start);
        // 调用每一个线程的 join 方法,阻塞当前线程
        tasks.forEach(t -> {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        // 当前线程阻塞,获取每一个查询线程的结果,并且加入 result 中
        tasks.stream().map(FlightQuery::get).forEach(result::addAll);
        return result;
    }
}

代码里面,相关的代码我已经注释,如果还是有不懂,建议去调试一下,还是不懂,给我留言,我给你讲。这个程序简单来说,就是主线程收到了search 请求之后, 交给了若干个査询线程分别进行工作,最后将每一个线程获取的航班数据进行统一的汇总。 由于每个航空公司的查询时间可能不一样,所以用了一个随机值来反应不同的查询速度,返回给客户端(打印到控制台)。

第四步:输出结果

在这里插入图片描述

总结:

如果我们去掉下面这段代码:则不能达到我们想要的效果。

// 调用每一个线程的 join 方法,阻塞当前线程
        tasks.forEach(t -> {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

有兴趣的小伙伴可以尝试以下,好了,本次分享到此结束。下节内容我们将分享线程之间的通信,希望对你有帮助。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值