繁体   English   中英

每个线程访问和修改二维数组中的一个元素

[英]Each thread accessing and modifying one element from a 2D array

我想要它,所以每次新线程通过run()方法时,它们都会访问 2D 数组的不同元素。

例如,第一个线程将访问和修改2DArray[0][0]

public void run() {
    while (running) {
        // Thread accesses 2DArray[0][0]
        DoSomething();
    }
}

然后第二个线程接管并访问/修改第二个索引2DArray[0][1]等等:

public void run() {
    while (running) {
        // Thread accesses 2DArray[0][1]
        DoSomething();
    }
}

如果我有一个 10x10 的矩阵,我想创建 10 个线程,每个线程同时处理 2D 数组中的 1 个元素

我似乎无法理解逻辑,有人有什么想法吗?

首先,java 没有二维 arrays,你只能创建一个 arrays 的数组。 所以它是 2DArray[0][1],而不是 2DArray[0,1]。 因此,您不应在不同的线程中处理辅助 arrays 的元素。 一个线程应该使用 2DArray[0] 而另一个线程应该使用 2DArray[1]

其次,由于您希望第二个线程仅在第一个线程完成处理前一个元素后接管,因此您无法从多线程中获得任何好处,那么您为什么要这样做。 您可以在单个线程中编写相同的代码。

第三,您只想更改第一行的值吗? 这看起来很奇怪。

如果您仍然有理由这样做,那么您应该创建一个锁,当前工作线程将获取该锁和一个用于保存当前元素索引的变量。

当活动线程工作时,其他线程等待获取锁。 并这样做,直到当前元素索引达到数组的长度。

更新

这是一个并行随机化所有行的解决方案。 请注意,线程池仅包含 4 个线程。 您可以将其更改为任何值,java 将为您进行平衡。

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

class RandomizeFunc implements Callable<Void> {
    private final int[] row;

    public RandomizeFunc(int[] row) {
        this.row = row;
    }

    @Override
    public Void call() throws Exception {
        ThreadLocalRandom localRandom = ThreadLocalRandom.current();
        for (int i = 0; i < row.length; i++) {
            int randomValue = localRandom.nextInt();
            row[i] = randomValue;
        }
        return null;
    }
}

public class RandomizeArray {
    public static void main(String[] args) throws InterruptedException {
        int[][] array = new int[10][];
        for (int i = 0; i < 10; i++) {
            array[i] = new int[10];
        }

        ExecutorService threadPool = Executors.newFixedThreadPool(4);

        List<Callable<Void>> tasks = new ArrayList<>(10);
        for (int i = 0; i < 10; i++) {
            tasks.add(new RandomizeFunc(array[i]));
        }
        threadPool.invokeAll(tasks);
        boolean workFinishedInTime = threadPool.awaitTermination(1, TimeUnit.SECONDS);
        if (!workFinishedInTime) {
            threadPool.shutdownNow();
        }
        for (int[] row : array) {
            for (int col : row) {
                System.out.print(col + " ");
            }
            System.out.println();
        }
    }
}

或者有一个使用裸线程的解决方案。 不推荐,但可能有助于了解发生了什么。

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

class RandomizingThread extends Thread {
    private final int[] row;

    public RandomizingThread(int[] row) {
        this.row = row;
    }

    @Override
    public void run() {
        ThreadLocalRandom localRandom = ThreadLocalRandom.current();
        for (int i = 0; i < row.length; i++) {
            int randomValue = localRandom.nextInt();
            row[i] = randomValue;
        }
    }
}

public class RandomizeArrayWithNakedThreads {
    public static void main(String[] args) throws InterruptedException {
        int[][] array = new int[10][];
        for (int i = 0; i < 10; i++) {
            array[i] = new int[10];
        }

        List<Thread> threadPool = new ArrayList<>(10);
        for (int i = 0; i < 10; i++) {
            RandomizingThread worker = new RandomizingThread(array[i]);
            worker.start();
            threadPool.add(worker);
        }
        for (Thread worker : threadPool) {
            worker.join();
        }
        for (int[] row : array) {
            for (int col : row) {
                System.out.print(col + " ");
            }
            System.out.println();
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM