如何创建4个线程拆分arr1并向ArrayList添加元素?
问题解答
问题1:创建4个线程向ArrayList添加元素
首先明确:ArrayList不是线程安全的,直接多线程调用add会出现元素丢失、数组越界等并发问题,必须做线程安全处理。以下是两种常用实现方案:
方案1:使用同步块保证线程安全
手动给ArrayList的修改操作加锁,确保同一时间只有一个线程能修改集合:
import java.util.ArrayList; import java.util.List; public class ArrayListThreadAdd { public static void main(String[] args) throws InterruptedException { List<Integer> list = new ArrayList<>(); Object lock = new Object(); // 所有线程共用同一把锁 // 创建4个线程,各自负责添加25个元素 Thread t1 = new Thread(() -> { for (int i = 0; i < 25; i++) { synchronized (lock) { list.add(i); } } }); Thread t2 = new Thread(() -> { for (int i = 25; i < 50; i++) { synchronized (lock) { list.add(i); } } }); Thread t3 = new Thread(() -> { for (int i = 50; i < 75; i++) { synchronized (lock) { list.add(i); } } }); Thread t4 = new Thread(() -> { for (int i = 75; i < 100; i++) { synchronized (lock) { list.add(i); } } }); // 启动所有线程 t1.start(); t2.start(); t3.start(); t4.start(); // 等待所有线程执行完毕,确保集合数据完整 t1.join(); t2.join(); t3.join(); t4.join(); System.out.println("集合大小:" + list.size()); // 稳定输出100 } }
方案2:使用线程安全的集合类
直接用Collections.synchronizedList包装ArrayList,或者使用CopyOnWriteArrayList(更适合读多写少的场景):
import java.util.ArrayList; import java.util.Collections; import java.util.List; public class SafeArrayListThreadAdd { public static void main(String[] args) throws InterruptedException { // 包装后得到线程安全的List List<Integer> list = Collections.synchronizedList(new ArrayList<>()); Thread t1 = new Thread(() -> { for (int i = 0; i < 25; i++) { list.add(i); } }); Thread t2 = new Thread(() -> { for (int i = 25; i < 50; i++) { list.add(i); } }); Thread t3 = new Thread(() -> { for (int i = 50; i < 75; i++) { list.add(i); } }); Thread t4 = new Thread(() -> { for (int i = 75; i < 100; i++) { list.add(i); } }); t1.start(); t2.start(); t3.start(); t4.start(); t1.join(); t2.join(); t3.join(); t4.join(); System.out.println("集合大小:" + list.size()); // 稳定输出100 } }
问题2:拆分arr1为4部分,多线程处理并填充intList1
需要完成三个核心操作:拆分数组区间、保证集合线程安全、等待所有线程处理完成后再执行后续逻辑。修改后的代码如下:
import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class MultiThreadProcess { // 假设arr1和arr2为类成员变量,也可通过参数传递给线程 private int[][] arr1; private int[] arr2; void process() throws IOException, InterruptedException { // 使用线程安全的List,避免并发修改问题 List<Integer> intList1 = Collections.synchronizedList(new ArrayList<>()); int totalLength = arr1.length; // 拆分4个区间,处理总长度无法被4整除的情况 int partSize = totalLength / 4; int start1 = 0, end1 = partSize; int start2 = end1, end2 = start2 + partSize; int start3 = end2, end3 = start3 + partSize; int start4 = end3, end4 = totalLength; // 创建4个线程,分别处理对应区间的arr1元素 Thread t1 = new Thread(() -> processPart(arr1, arr2, intList1, start1, end1)); Thread t2 = new Thread(() -> processPart(arr1, arr2, intList1, start2, end2)); Thread t3 = new Thread(() -> processPart(arr1, arr2, intList1, start3, end3)); Thread t4 = new Thread(() -> processPart(arr1, arr2, intList1, start4, end4)); // 启动所有线程 t1.start(); t2.start(); t3.start(); t4.start(); // 必须等待所有线程执行完毕,否则后续使用intList1时数据可能不完整 t1.join(); t2.join(); t3.join(); t4.join(); if (intList1.size() > 0) { // 原业务逻辑代码 // some code here } } // 提取公共处理逻辑,复用代码 private void processPart(int[][] arr, int[] arr2, List<Integer> resultList, int start, int end) { for (int i = start; i < end; i++) { for (int j = 1; j < 13; j++) { if (arr[i][2] == arr2[j]) { resultList.add(arr[i][0]); break; } } } } }
关键说明:
- 拆分逻辑:将arr1按长度平均拆分,最后一个线程处理剩余元素,避免总长度无法被4整除时的遗漏
- 线程安全:通过
Collections.synchronizedList包装ArrayList,确保多线程add操作安全;也可在resultList.add处加同步块替代 - 等待机制:用
join()让主线程等待所有工作线程完成,保证后续业务逻辑能拿到完整的intList1数据
内容的提问来源于stack exchange,提问作者user406
相关产品推荐
相关产品推荐

