一 问题描述
通过多线程查询多家航班信息,并合并输出。
二 问题分析
该例子是典型的串行任务局部并行化处理,将每一家航空公司的查询都交给一个线程去工作,然后在它们结束工作之后统一对数据进行整理,这样就可以极大节约时间,从而提高用户体验。
三 代码
1 FightQuery
package fightquery;
import java.util.List;
public interface FightQuery {
List<String> get();
}
2?FightQueryTask
package fightquery;
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 + "]");
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() + "-航班1-" + randomval);
this.flightList.add(getName() + "-航班2-" + randomval);
System.out.printf("The Fight:%s list query successful \n", getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
3?FightQueryTest
package fightquery;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static java.util.stream.Collectors.toList;
public class FightQueryTest {
// 各大航空公司
private static List<String> fightCompany = Arrays.asList("南方航空", "东方方航空", "海南航空");
public static void main(String[] args) {
List<String> restlts = search("上海", "南京");
System.out.println("=============结果===================");
restlts.forEach(System.out::println);
}
private static List<String> search(String original, String dest) {
final List<String> result = new ArrayList<>();
// 创建查询航班信息的线程列表
List<FightQueryTask> tasks = fightCompany.stream().map(f -> createSearchTask(f, original, dest)).collect(toList());
// 分别启动这几个线程
tasks.forEach(Thread::start);
// 分别调用每一个线程的 join 方法,阻塞当前线程
tasks.forEach(t -> {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// 获取每一个线程的查询结果,并且加入到 result
for (FightQueryTask task : tasks) {
List<String> stringList = task.get();
result.addAll(stringList);
}
return result;
}
private static FightQueryTask createSearchTask(String fight, String original, String dest) {
return new FightQueryTask(fight, original, dest);
}
}
四?测试结果
[南方航空]-query from 上海 to 南京
[东方方航空]-query from 上海 to 南京
[海南航空]-query from 上海 to 南京
The Fight:[南方航空] list query successful
The Fight:[海南航空] list query successful
The Fight:[东方方航空] list query successful
=============结果===================
[南方航空]-航班1-3
[南方航空]-航班2-3
[东方方航空]-航班1-9
[东方方航空]-航班2-9
[海南航空]-航班1-6
[海南航空]-航班2-6
|