java - 每个线程访问和修改二维数组中的一个元素
问题描述
我想要它,所以每次新线程通过该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没有二维数组,你只能创建数组数组。所以它是 2DArray[0][1],而不是 2DArray[0,1]。因此,您不应该在不同的线程中处理辅助数组的元素。一个线程应该使用 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();
}
}
}
推荐阅读
- user-interface - 鼠标悬停时如何隐藏 GUI?
- scala - 如何使用 AsyncFeatureSpec?
- node.js - 如何在带有上下文的 Koa 中间件中传递参数?
- android - 如何在滚动视图布局中修复页脚 alignParentBottom="true"
- postgresql - postgre 有 map 和 set 结构吗(如 C++ 中的 STL)?
- excel - 如何在嵌套if条件下搜索文本中的文本?
- c# - 复选框删除并在列表中创建一段文本
- php - Issues ordering a resut from query
- css - 绝对位置 - 在屏幕范围内浮动(反应)
- python - 使用循环和条件时如何从列表中获取唯一值