问题描述:A服务调用B服务多接口时,如何设计接口来缩短响应时间
解决:callable、futureTask、线程阻塞
代码示例,以获取详情(订单信息和快递信息)为例。
(1)改进代码(串行模式):
@Override
public String queryOrderDetailInfo(String orderId) {
String orderInfo = queryService.getOrderInfo(orderId); //先执行
String deliverInfo = queryService.geDeliverInfo(orderId); //后执行
return "订单信息:" + orderInfo + "---------快递信息:" + deliverInfo;
}
改进前代码为串行模式,先查询订单信息,再查询快递信息,总时间为两个查询时间的和。
(2)改进后代码(并行模式):
//首先定义线程池(这里第一种方式阿里巴巴的校验插件会报错,故改为手动创建线程池)
// static ExecutorService threadPool = Executors.newFixedTreadPool(nTreads:10);
private static ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("thread-call-runner-%d").build(); private static ExecutorService threadPool = new ThreadPoolExecutor(10,20,200L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue(),namedThreadFactory);
@Override
public String queryOrderDetailInfo(final String orderId) {
/* new Thread(new Runnable() {
@Override
public void run() { //此方法返回值为void,固不用此方法,我们需要获取信息
}
}).start(); */
Callable
@Override
public String call() throws Exception { //call方法相当于上面的run方法
String orderInfo = queryService.getOrderInfo(orderId);
return orderInfo;
}
}
Callable
@Override
public String call() throws Exception { //call方法相当于上面的run方法
String deliverInfo = queryService.getDeliverInfo(orderId);
return deliverInfo ;
}
}
//启动
FutureTask
FutureTask
// new Thread(orderInfoTask ).start(); //正常的启动方法,这里不用
//用线程池启动
threadPool.submit(orderInfoTask );
threadPool.submit(deliverInfoTask );
String orderInfoF = null;
String deliverInfoF = null;
try {
//获取返回值
orderInfoF = orderInfoTask.get(); //在没有拿到结果前,线程阻塞
deliverInfoF = deliverInfoTask.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return "订单信息:" + orderInfoF + "---------快递信息:" + deliverInfoF;
}