packagecom.zhuyl.base.requestMerge;importjava.math.BigDecimal;importjava.util.ArrayList;importjava.util.HashMap;importjava.util.List;import java.util.concurrent.*;importjava.util.stream.Collectors;importjava.util.stream.IntStream;importcom.alibaba.fastjson.JSON;public classRequestMergeDemo {private final static int THREAD_COUNT = 10000;private static volatile intcount;public static voidmain(String[] args) {
requestMerge();
}/*** 模拟高并发下的10000次接口调用,进行请求合并*/
public static voidrequestMerge() {
RequestMergeDemo requestMergeDemo= newRequestMergeDemo();//CyclicBarrier cyclicBarrier = new CyclicBarrier(threadCount);
Runnable runnable = () ->{try{//循环屏障//cyclicBarrier.await();
requestMergeDemo.getById(Thread.currentThread().getName());
}catch(Exception e) {
e.printStackTrace();
}
};
IntStream.rangeClosed(1, THREAD_COUNT).forEach(i ->{new Thread(runnable, "id_" +i).start();
});
}/*** 线程安全*/
private LinkedBlockingQueuelinkedBlockingQueue;private Listrequests;//第一次加载该类时添加个定时任务 每10ms执行一次 spring中可以使用 @PostConstruct 注释
publicRequestMergeDemo() {
linkedBlockingQueue= newLinkedBlockingQueue();
ScheduledExecutorService scheduledExecutorService= new ScheduledThreadPoolExecutor(20);
scheduledExecutorService.scheduleAtFixedRate(()->{int size =linkedBlockingQueue.size();if (size <= 0) return;
requests= new ArrayList<>();
HashMap map = new HashMap<>();
List codes = new ArrayList<>();for (int i = 0; i < size; i++) {
Request request=linkedBlockingQueue.poll();
requests.add(request);
map.put(request.goodsCode, request.future);
codes.add(request.goodsCode);
}
System.out.println("第 " + ++count + " 次批量处理,入参: " +JSON.toJSONString(codes));
List goodsList =getByIds(codes);
System.out.println("第 " + count + " 次批量处理,出参: " +JSON.toJSONString(goodsList));//循环把处理结果放入到对应的请求线程中
goodsList.forEach(e ->{
CompletableFuture completableFuture=map.get(e.getGoodsCode());if (completableFuture != null) {
completableFuture.complete(e);
}
});
},0, 10, TimeUnit.MILLISECONDS);
}/*** 单个查询商品
*
*@paramgoodsCode
*@return
*/
public Goods getById(String goodsCode) throwsExecutionException, InterruptedException {/*Goods goods=new Goods();
goods.setGoodsCode(goodsCode);
goods.setGoodsName("鞋子");
goods.setPrice(new BigDecimal(2000));
return goods;*/Request request= newRequest();
request.goodsCode=goodsCode;
request.future= newCompletableFuture();
linkedBlockingQueue.add(request);
Future future =request.future;returnfuture.get();
}/*** 批量查询商品信息
*
*@paramgoodsCode
*@return
*/
public List getByIds(ListgoodsCode) {
List goodsList = goodsCode.parallelStream().map(e ->{
Goods goods= newGoods();
goods.setGoodsCode(e);
goods.setGoodsName("鞋子_" +count);
goods.setPrice(newBigDecimal(count));returngoods;
}).collect(Collectors.toList());returngoodsList;
}classGoods {privateString goodsCode;privateString goodsName;privateBigDecimal price;publicString getGoodsCode() {returngoodsCode;
}public voidsetGoodsCode(String goodsCode) {this.goodsCode =goodsCode;
}publicString getGoodsName() {returngoodsName;
}public voidsetGoodsName(String goodsName) {this.goodsName =goodsName;
}publicBigDecimal getPrice() {returnprice;
}public voidsetPrice(BigDecimal price) {this.price =price;
}
}class Request{
String goodsCode;
CompletableFuturefuture;
}
}