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

多线程并行计算哈希存入ArrayList<String>结果缺失如何修复

问题根因

  • 第一,你启动所有线程后,没有等待所有子线程执行完成,主线程直接就执行了打印列表大小的逻辑,此时大部分子线程还没来得及执行add操作,所以每次统计的大小都随机,这是你注释interrupt后问题依旧的核心原因。
  • 第二,你调用的interrupt()会中断正在执行的线程,如果子线程还没完成哈希计算和插入操作就被中断,也会导致部分结果丢失。
  • 第三,最初用的ArrayList本身是非线程安全的,多线程同时add会出现并发修改异常、元素覆盖等问题,你替换成同步列表是对的,但这只解决了其中一个问题。

修正代码

import org.apache.commons.codec.digest.DigestUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class HashCalculateTest {
    public static void main(String[] args) throws InterruptedException {
        ArrayList<Thread> threadList = new ArrayList<>();
        // 使用线程安全的同步列表避免并发插入异常
        List<String> threadListStrSync = Collections.synchronizedList(new ArrayList<>());
        int threadNumber = 100;
        for (int i = 0; i < threadNumber; i++) {
            String tId = String.valueOf(i);
            Thread thr = new Thread(() -> {
                threadListStrSync.add(calculateHash(tId));
            });
            threadList.add(thr);
        }

        // 启动所有线程
        for (Thread thr : threadList) {
            thr.start();
        }
        
        // 新增:等待所有子线程执行完成,再执行后续逻辑
        for (Thread thr : threadList) {
            thr.join();
        }

        System.out.println("Size of ArrayList<String> is: " + threadListStrSync.size());
        System.out.println("Size of ArrayList<Thread> is: " + threadList.size());
    }

    public static String calculateHash(String tId) {
        return DigestUtils.sha256Hex(tId);
    }
}

关键修改说明

  1. 移除了interrupt()调用逻辑:你的子线程没有需要主动打断的阻塞逻辑,中断操作只会打断正常的计算和插入流程。
  2. 新增join()逻辑:主线程会逐个等待所有子线程执行完毕后,再打印列表大小,保证所有add操作都已完成。
  3. 保留同步列表的使用,规避多线程插入的并发安全问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 20:09:03