多线程并发问题解决
有这样一个需求:查询数据库里的多张表的数据量,并按从大到小的顺序排序。
首先想到的就是按传统的做法,去循环查询每一张表的数据量,再放到一个集合进行排序。
这样也能实现,但是查询速度太慢,如果有上百张表,且每张表都是上百万条数据量的,
这样时间需要非常久,这个时候就要用到多线程了,充分调动CPU的资源。
1 //创建线程池 2 ExecutorService exe = Executors.newCachedThreadPool(); 3 //创建任务数组 4 CompletableFuture[] list1 = new CompletableFuture[securityDictionaryFroms.size()]; 5 //循环创建任务并把任务加到任务数组 6 for (int i = 0; i < securityDictionaryFroms.size(); i++) { 7 SecurityDictionaryFrom securityDictionaryFrom = securityDictionaryFroms.get(i); 8 //创建任务实现类实例 9 CountTask countTask = new CountTask(securityDictionaryFrom.getDicValue(), getJdbcTemplate()); 10 //定义任务执行完成后需要进行的后续操作 11 CompletableFuture completableFuture = CompletableFuture.supplyAsync(countTask, exe).whenComplete((result, e) -> { 12 Temp temp = new Temp(); 13 temp.setTableNameCn(securityDictionaryFrom.getDicName()); 14 temp.setTableNameEn(securityDictionaryFrom.getDicValue()); 15 temp.setDataSum(result); 16 list.add(temp); 17 }).exceptionally((e) -> { 18 e.printStackTrace(); 19 return 0; 20 }); 21 //将任务加入任务数组 22 list1[i] = completableFuture; 23 } 24 //将任务数组交给一个任务来调度 25 CompletableFuture<Void> all = CompletableFuture.allOf(list1).thenApply(x -> { 26 log.info("all"); 27 return null; 28 }); 29 //阻塞直至所有任务都执行完成 30 Void aVoid = all.get(); 31 //关闭线程池 32 exe.shutdown(); 33 list2 = list; 34 //对查询结果进行排序 35 list2 = list2.stream().sorted(Comparator.comparing(Temp::getDataSum).reversed()).collect(Collectors.toList());