多线程并行计算哈希存入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); } }
关键修改说明
- 移除了
interrupt()调用逻辑:你的子线程没有需要主动打断的阻塞逻辑,中断操作只会打断正常的计算和插入流程。 - 新增
join()逻辑:主线程会逐个等待所有子线程执行完毕后,再打印列表大小,保证所有add操作都已完成。 - 保留同步列表的使用,规避多线程插入的并发安全问题。
内容的提问来源于stack exchange,提问作者Questioner
相关产品推荐
相关产品推荐

