记录V站中看见的改造以下 For 循环的各种处理方式
for(int i = 0; i < list.size() ; i ++){
List resultList = HttpRequest.post(url).body(list.get(i));
for(int j = 0 ; j < resultList.size() ; j++){
var resultA = functionA(resultList.get(j));
var resultB = functionB(resultA);
var resultC = functionC(resultB);
}
}
其中 list 数据来源 API 接口,数据量在 100 到 1000 不等。functionA 、B 、C 都有业务逻辑( Http 请求,数据库查询等,都是需要串行执行的)。目前单线程运行比较慢,想问下有什么比较好的办法可以提高处理效率?
我打算使用多线程并行处理 list 的数据,但是里面那层 for 循环数据量也比较大(多的可能有 1 万条),里面那层不知道有没有办法也可以加快效率的?或者针对这类场景是否有比较通用的解决办法?
解决方法记录:
第一种->
如果只需要保证 functionABC 的调用顺序可以用 Fork/Join
resultList.parallelStream()
.map(o -> functionA(o))
.map(o -> functionB(o))
.map(o -> functionC(o))
.collect(Collectors.toList());
第二种:
不要用 parallelStream 去做 io 操作,parallelStream 只推荐在 cpu 密集型任务时使用
你这个用 completablefuture 是很合适的
第三种:
先从业务上调整, 能整合的整合, 能合并的合并.
其次同步转异步, 事件驱动用消息队列+本地事件表,根据具体的消费能力调整并发即可.
你这个量用单进程多线程做稳定性太差,吞吐量太低,没啥可观测性.
第四种:
disruptor 框架了解一下,或者使用 1.8 的 CompletionService
disruptor.handleEventsWithWorkerPool(poolA)
.thenHandleEventsWithWorkerPool(poolB)
.thenHandleEventsWithWorkerPool(poolC)
.thenHandleEventsWithWorkerPool(poolD)
第五种: 线程池,以及 resultList 需要和数据库打交道的一起提出来,切分后一条 sql 处理若干个,CPU 计算很快的,主要还是 IO