最近在项目中需要根据角色拿对应任务(activiti 中的内容),再根据任务拿工单集(任务跟工单为多对一的关系,所以还需过滤掉重复的工单),获得最终结果集的耗时较大,所以考虑从多线程方向优化。
这些操作在一个for循环里涉及两处数据库查询IO,但IO的阻塞不严重,不属于IO密集型的多线程设计条件,所以采用线程池,优化的效果不是很好(对于IO阻塞系数较小的应用优化,多线程的使用,CPU在线程非阻塞的状态下切换上下文,消耗很大,同时还得加上创建线程的开销);采用concurrent包的Stream来进行并发流式的处理,优化效果还比较可观。
现针对三种不同的实现方式和执行效果通列如下:
原始for循环:
//同组测试数据,2038ms 结果集稳定
方法体:
List<WorkOrder> content = new ArrayList<WorkOrder>();
Map<String,Integer> widMap=new HashMap<String,Integer>();
for (String id : ids) {
List<Task> tasks = taskService.createTaskQuery()
.taskCandidateGroup(id).active().list();
//同组测试数据,2038ms 结果集稳定
for (Task task : tasks) {
ProcessInstance pi = runtimeService
.createProcessInstanceQuery()
.processInstanceId(task.getProcessInstanceId())
.singleResult();
String workOrderId = pi.getBusinessKey();
if(!widMap.containsKey(workOrderId)){
WorkOrder wo = workOrderService.findStartedWorkOrderAnd(
workOrderId, Constants.WORKORDER.CONFIGURED,
Constants.WORKORDER.INPROCESSED,
Constants.WORKORDER.UNFILLED);
if(wo!=null){
content.add(wo);
}
widMap.put(workOrderId, 1);
}
}
}
并行流