1,多线程中join的核心说法
当join线程A时,会使得当前线程B,进入BLOCKED,直到线程A结束生命周期或者达到预设定的时间;
2,适用场景:
场景1:当一次查询中,有需要调用多个外部服务的接口,并且这些接口之间相对独立时,可以考虑用这个实现。
场景2:当分库分表时,也可以考虑通过这样的方式,提高查询效率。
3,核心思想:
串行任务局部并行处理:即
1st 每个查询服务为一个线程,启动后,调用join方法,阻塞主线程。
2nd 当每个线程的生命周期结束后,再由主线程进行数据的整合,返回给前端或者客户端。
4,代码举例
查询航班信息
查询线程的逻辑
package test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
public class FlightQueryTask extends Thread {
private final String orign;
private final String dest;
private List<String> result = new ArrayList<>();
public FlightQueryTask(String company,String orign,String dest){
super('['+company+']');
this.orign = orign;
this.dest = dest;
}
public List<String> getResult(){
return this.result;
}
@Override
public void run() {
System.out.printf("%s query from %s to %s \n",getName(),this.orign,this.dest);
try{
int randValue = ThreadLocalRandom.current().nextInt(10);
TimeUnit.SECONDS.sleep(randValue);
this.result.add(getName()+"-"+randValue);
System.out.printf("%s query successfully\n",getName());
}catch (Exception e){
e.printStackTrace();
}
}
}
业务主线程逻辑:
package test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class FlightQueryExample {
private static List<String> companys = Arrays.asList("CEA","CSA","CCA");
public static List<String> search(List<String> flighCompays,String origin,String dest){
List<String> result = new ArrayList<>();
List<FlightQueryTask> tasks = companys.stream()
.map(company -> {
return new FlightQueryTask(company,origin,dest);
}).collect(Collectors.toList());
tasks.forEach(Thread::start);
tasks.forEach(t -> {
try {
t.join();
}catch (InterruptedException e){
}
});
tasks.stream().map(FlightQueryTask::getResult).forEach(result::addAll);
return result;
}
public static void main(String[] args){
List<String> result = search(companys, "SH", "BJ");
System.out.println("==============结果为=======");
result.forEach(System.out::println);
}
}
4,参考书籍:
《JAVA高并发编程详解 多线程与架构设计》