You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java JSONArray迭代并行化实现需求及代码优化问询

嘿,针对你这段需要并行化的JSON数组遍历代码,我给你几个实用的Java实现方案——毕竟你的操作相互独立,完全是并行处理的绝佳场景😉:

并行化JSON数组遍历的几种Java实现方案

方案1:使用Java 8+ Stream API(最简洁省心)

Stream API的并行流(parallelStream)是处理这类场景的首选,JVM会自动帮你管理线程池,不用手动折腾线程逻辑。不过有个关键细节要注意:你原来定义的ArrayList<StockQuote> topGainers不是线程安全集合,如果直接在并行操作里调用topGainers.add(),大概率会出现并发问题。推荐用下面两种方式解决:

方式A:用Stream收集器生成结果(更推荐)

这种方式内部会自动处理线程安全,代码也更简洁:

List<StockQuote> topGainers;
JSONObject jsonObject = (JSONObject) new JSONParser().parse(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
JSONArray dataArray = (JSONArray) jsonObject.get("data");

// 并行遍历并收集结果
topGainers = IntStream.range(0, dataArray.size())
        .parallel()
        .mapToObj(iter -> {
            JSONObject temp = (JSONObject) dataArray.get(iter);
            // 这里写你原来的处理逻辑,比如解析temp为StockQuote对象
            StockQuote quote = parseStockQuote(temp); // 假设你有这个解析方法
            System.out.println(quote); // 你的打印逻辑
            return quote;
        })
        .collect(Collectors.toList());

方式B:改用线程安全集合

如果你一定要保留原来的集合引用,可以换成CopyOnWriteArrayList这类线程安全的实现:

List<StockQuote> topGainers = new CopyOnWriteArrayList<>();
JSONObject jsonObject = (JSONObject) new JSONParser().parse(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
JSONArray dataArray = (JSONArray) jsonObject.get("data");

// 并行遍历并添加元素
IntStream.range(0, dataArray.size()).parallel().forEach(iter -> {
    JSONObject temp = (JSONObject) dataArray.get(iter);
    StockQuote quote = parseStockQuote(temp);
    topGainers.add(quote);
    System.out.println(quote);
});

要是你需要自定义线程池大小(比如不想用默认的公共池),还可以用ForkJoinPool来包装并行流:

// 指定4个线程的自定义池
ForkJoinPool customPool = new ForkJoinPool(4);
List<StockQuote> topGainers = customPool.submit(() -> 
    IntStream.range(0, dataArray.size())
            .parallel()
            .mapToObj(iter -> {
                JSONObject temp = (JSONObject) dataArray.get(iter);
                return parseStockQuote(temp);
            })
            .collect(Collectors.toList())
).join();
customPool.shutdown(); // 用完记得关闭池

方案2:使用ExecutorService手动管理线程池

如果需要更精细地控制线程参数(比如核心线程数、队列大小),或者要兼容Java 8之前的版本,可以手动用线程池实现:

List<StockQuote> topGainers = new ArrayList<>();
JSONObject jsonObject = (JSONObject) new JSONParser().parse(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
JSONArray dataArray = (JSONArray) jsonObject.get("data");

// 创建固定大小的线程池,大小设为CPU核心数是比较合理的选择
ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
List<Future<StockQuote>> futures = new ArrayList<>();

// 提交所有并行任务
for (int iter = 0; iter < dataArray.size(); iter++) {
    final int index = iter; // 匿名内部类需要引用final变量
    futures.add(executor.submit(() -> {
        JSONObject temp = (JSONObject) dataArray.get(index);
        StockQuote quote = parseStockQuote(temp);
        System.out.println(quote);
        return quote;
    }));
}

// 等待所有任务完成,收集结果
for (Future<StockQuote> future : futures) {
    try {
        topGainers.add(future.get());
    } catch (InterruptedException | ExecutionException e) {
        // 记得处理异常,比如打印日志或者做降级处理
        e.printStackTrace();
    }
}

// 用完线程池一定要关闭
executor.shutdown();

几个关键注意事项

  • 线程安全优先:只要涉及共享集合的修改,一定要用线程安全的实现,或者依赖Stream收集器的线程安全机制,不然会出现数据错乱的问题。
  • 异常别忽略:并行处理时的异常容易被隐藏,比如Stream并行流会抛出CompletionException,Future需要捕获ExecutionException,一定要妥善处理。
  • 别盲目并行:如果你的JSON数组元素很少(比如少于100个),并行处理的线程开销可能会抵消性能收益,建议在数据量较大的时候再用并行。

内容的提问来源于stack exchange,提问作者Prateek Narendra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:37:53