欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Thread join方法结合实战

程序员文章站 2022-05-04 10:10:04
...

       该例子是典型的串行任务局部并行化处理,用户在App客户端输入出发地“北京”和目的地上海,服务器接收到这个请求之后, 先来验证用户的信息,然后到各大航空公司的接口查询信息,最后经过整理加工返回给客户端,每一个航空公司的接口不会都一样, 获取的数据格式也不一样,查询的速度也存在这差异,如果再跟航空公司进行串行化交互(逐个的查询),很明显客户端需要等待很长的时间。 这样的话,用户的体验很差。我们将每一个航空公司的查询都交给一个线程去做,然后再他们结束工作之后统一对数据进行整理, 这样就可以极大的节约时间,从而提高用户体验效果。

说明:本次只是单纯用Thread的api来实现这种效果,当然JDK也自带了很多高级工具,比如CountDownLatch和CyclicBarrier都可以完成类似的功能,在此不详细展开。

import java.util.List;

public interface FightQuery {
    List<String> get();
}
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

public class FightQueryTask extends Thread implements FightQuery{

    private final String origin;
    private final String destination;
    private final List<String> flightList=new ArrayList<>();

    public FightQueryTask(String airLine, String origin, String destination){
        super("["+airLine+"]");//Thread的名字构造方法
        this.origin=origin;
        this.destination=destination;
    }

    @Override
    public List<String> get() {
        return this.flightList;
    }

    @Override
    public void run() {
        System.out.printf("%s-query from %s to %s \n",getName(),origin,destination);
        int randomVal = ThreadLocalRandom.current().nextInt(10);
        try {
            TimeUnit.SECONDS.sleep(randomVal);
            this.flightList.add(getName()+"-"+randomVal);
            System.out.printf("The Flight:%s list query successful\n",getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class FlightQueryExample {
    //合作的各大航空公司
    private static List<String> fightCompany = Arrays.asList("CSA", "CEA", "HNA");
    public static void main(String[] args) {
        List<String> result = search("SH", "BJ");
        System.out.println("=========result==========");
        result.forEach(System.out::println);
    }

    private static List<String> search(String origin,String dest){
        final List<String> result=new ArrayList<>();
        //创建查询航班信息的线程列表
        List<FightQueryTask> fightQueryTaskList = fightCompany.stream().map(f -> createSearchTask(f, origin, dest)).collect(Collectors.toList());
        //分别启动这几个线程
        fightQueryTaskList.forEach(Thread::start);
        //分别调用每一个线程的join方法,阻塞当前线程
        fightQueryTaskList.forEach(fightQueryTask -> {
            try {
                fightQueryTask.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        //在此之前,当前线程会阻塞住,获取每一个查询线程的结果,并且加入到result中
        fightQueryTaskList.stream().map(FightQueryTask::get).forEach(result::addAll);
        return result;
    }
    private static FightQueryTask createSearchTask(String flight,String ori,String dest){
        return new FightQueryTask(flight,ori,dest);
    }
}

运行结果:

Thread join方法结合实战

相关标签: Java高并发编程