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

如何创建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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 00:18:20