CompletableFuture的写法是否有错误,因为运行效率并没有提升很多

李11
  • 186
            Integer oneTimeCount = 50;
            List<List<OrderEditableConf>> createListList = Lists.partition(createList, oneTimeCount);
            List<CompletableFuture<Integer>> futures = new ArrayList<>();
            for (int i = 0; i < createListList.size(); i++) {
                List<OrderEditableConf> oneCreate = createListList.get(i);
                futures.add(CompletableFuture.supplyAsync(() -> {
                    Integer inserResult = 0;
                    oneCreate.size();
                    if(oneCreate.size() > 0) {
                        Map<String, Object> futuresParams = new HashMap<>();
                        futuresParams.put("map", oneCreate);
                        SupplierOrderServiceResponse futuresResponse = SupplierOrderServiceClient.request("/rest/orderEditableConf/insertOrderEditableConfList", futuresParams);
                        inserResult =  JSONObject.parseObject(futuresResponse.getData().toString(), Integer.class);
                    }
                    if(inserResult != null && inserResult == 1) {
                        return oneCreate.size();
                    } else {
                        return 0;
                    }
                }).handle((res, e) -> {
                    if(e != null || res == null) {
                        return 0;
                    }
                    return res;
                }));
            }
            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
            Long totalInsert = 0l;
            for (CompletableFuture<Integer> future : futures) {
                try {
                    Integer oneTimeRes = future.get();
                    totalInsert = totalInsert + oneTimeRes;
                } catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                }
            }
            

如上代码,我有一个集合要进行 insert,想通过 CompletableFuture并发然后全部结束之后返回页面结果,集合大小20000多,分成500为一组进行insert, 按道理说,每个线程的数量越小就应该越快,但实际测下来500个一组合100个一组的运行时间差不多,有没有懂的人帮忙看一下,是不是有错误造成并没有并行

回复
阅读 713
1 个回答
✓ 已被采纳

CompletableFuture.supplyAsync你没有指定自定义线程池,那么应该采用的应该是
ForkJoinPool.commonPool,默认线程大小是Runtime.getRuntime().availableProcessors() - 1
从你的代码来看,你的任务应该是IO密集
这个线程大小按道理不合适,严重的情况下可能阻塞其他逻辑执行
IO密集的话,不扩大线程数只是分片大小调整的话,理论上是提升不了速度的,因为线程实际逻辑执行很快,大多数时间都在等待IO返回,那么一个线程执行多少个已经不重要了,重要的是同时有多少线程再帮你执行

如果想变快,可以考虑传入第二个参数自定义线程池
不过我感觉更好的方法可以是,改写
SupplierOrderServiceClient.request,用IO多路复用的客户端

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏