ptn多线程使用实例:
在ptn项目中由于网管系统抓取的tunnel数据量较大,每条tunnel都需要做相对于的业务处理, 传统的for循环方式中每一个tunnel去依次执行,效率很慢
现将大的tunnerl list拆分为n个list ,每个list都是一个线程,提高效率;
详情如下:
jdk 自带线程池结果管理器:ExecutorCompletionService 它将BlockingQueue 和Executor 封装起来。然后使用ExecutorCompletionService.submit()方法提交任务。
1.新建线程池
ExecutorService exs = Executors.newFixedThreadPool(analysisThreadNum);
2.线程池管理器,可以获取多线程处理结果
CompletionService<Map<String, Object>> completionService = new ExecutorCompletionService<>(exs);
3.将一个list切分为多个list 均分tunnullist
List<List<Tunnel>> averageAssign = CommUtils.averageAssign(tunnels, analysisThreadNum);
4.遍历averageAssign 均分list
List<Future<Map<String, Object>>> futureList = new ArrayList<>();
for (List<Tunnel> list : averageAssign) {
futureList.add(completionService.submit(new LogicPathOverlappedCheckTask(list, portNameLinkIdMap,tunnelClassifyMap, allNEs, allBoards, allTopoLines)));
}
5.合并多线程处理结果
for (int i = 1, curr = 0, length = futureList.size(); i <= length; i++) {
// 采用completionService.take(),内部维护阻塞队列,任务先完成的先获取到
Map<String, Object> result = completionService.take().get();
lineNumber += MapUtils.getInteger(result, "lineNumber", 0);
boardNumber += MapUtils.getInteger(result, "boardNumber", 0);
neNumber += MapUtils.getInteger(result, "neNumber", 0);
lineResultList.addAll((List<Map<String, Object>>) result.get("lineResultList"));
boardResultList.addAll((List<Map<String, Object>>) result.get("boardResultList"));
neResultList.addAll((List<Map<String, Object>>) result.get("neResultList"));
curr += MapUtils.getInteger(result, "listSize");
logger.debug("Thread : " + i + " is done. [" + curr + "/" + totailNumber+ "] tunnel logic path overlapped check is done ..");
}
6.关闭线程池
exs.shutdown();