我有一个随机整数的2d矩阵。我想在每一行中找到最小值和最大值(每行由不同的线程完成),然后我想整理结果并在所有矩阵中找到最小值和最大值。这是main中的代码:
Type2
答案 0 :(得分:1)
100个线程疯狂。我怀疑你可以证明使用一个线程来证明你只需创建一个线程。不要说为100x200 randoms分配空间并不是绝对必要的。您可以简单地随机调用20k次并对这些值执行相同的计算。
然而,让我们假设这是一个学习练习。如果您希望并行执行计算,则需要任意细分网格,以便每个线程都有自己的部分而不会重叠。然后,为了在线程中使用它,您只需将该实例传递给MinMaxFinder线程。
类似于:
class MinMaxFinder extends Thread {
private int minRow, maxRow, minColumn, maxColumn;
private Double[][] grid;
public MinMaxFinder(Double[][] grid) {
this.grid = grid;
}
public void start(int minRow, int maxRow, int minColumn, int maxColumn) {
this.minRow = minRow;
this.maxRow = maxRow;
this.minColumn = minColumn;
this.maxColumn = maxColumn;
super.start();
}
public void start() {
// perform search
}
}
这里没有什么神奇的事情发生。只要您没有写入网格并且不与网格重叠,就不存在并发问题的风险。
我建议你在处理大量线程时考虑ThreadPoolExecutor。它有许多有用的方法来组织线程并可能重用它们。
答案 1 :(得分:1)
如果你想从并行线程收集结果,我建议使用Future
抽象。特别是我会在FutureTask
实用程序的帮助下完成此任务。
public class RandomMatrixMinMax {
public static void main(String[] args) {
double maxGlob = 0.0;// max in all matrix
double minGlob = 1.0;// min in all matrix
final Double[][] x = generateData(100, 200);// generate matrix
final MinMaxFinderTask[] t = new MinMaxFinderTask[100];// make hundred
// threads -
// MinMaxFinder extends Thread
for (int i = 0; i < 100; i++) {
t[i] = new MinMaxFinderTask(x[i]);
new Thread(t[i]).start();
} // end of for
try {
for (int i = 0; i < 100; i++) {
if (t[i].get().getMax() > maxGlob) {
maxGlob = t[i].get().getMax();
}
if (t[i].get().getMin() < minGlob) {
minGlob = t[i].get().getMin();
}
}
} catch (final InterruptedException | ExecutionException e) {
}
// when done with all threads, print global max and min values for all
// matrix
System.out.println("Max is: " + maxGlob + " and min is: " + minGlob);
}// end of main
private static Double[][] generateData(int rows, int cols) {
final Double[][] randomMatrix = new Double[rows][cols];
final Random random = new Random();
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
randomMatrix[j][i] = random.nextDouble();
}
}
return randomMatrix;
}
private static class MinMaxResult {
private Double min;
private Double max;
public MinMaxResult(Double min, Double max) {
this.min = min;
this.max = max;
}
public Double getMin() {
return min;
}
public void setMin(Double min) {
this.min = min;
}
public Double getMax() {
return max;
}
public void setMax(Double max) {
this.max = max;
}
}
private static class MinMaxFinderTask extends FutureTask<MinMaxResult> {
public MinMaxFinderTask(Double[] row) {
super(new MinMaxCalculator(row));
}
}
private static class MinMaxCalculator implements Callable<MinMaxResult> {
private final Double[] row;
public MinMaxCalculator(Double[] row) {
this.row = row;
}
@Override
public MinMaxResult call() throws Exception {
Double min = row[0];
Double max = row[0];
for (int i = 1; i < row.length; i++) {
if (row[i] < min) {
min = row[i];
}
if (row[i] > max) {
max = row[i];
}
}
return new MinMaxResult(min, max);
}
}
}
无论如何我同意Neil,这个简单任务的100个线程太多了。作为ThreadPoolExecutor
的替代,您可以将计算的并行性委托给Java 8引入的新Stream API。
在Java 8中,您的应用程序可能是:
public class RandomMatrixMinMax {
public static void main(String[] args) {
final Double[][] x = generateData(100, 200);
// obtain an array with min/max of each row of the matrix. The
// intermediate operation 'parallel' makes the computation parallel.
final MinMaxResult[] rowResults = Arrays.stream(x).parallel()
.map(row -> new MinMaxResult(Arrays.stream(row).min(Double::compare).get(),
Arrays.stream(row).max(Double::compare).get()))
.toArray(size -> new MinMaxResult[size]);
final Double maxGlob = Arrays.stream(rowResults).map(MinMaxResult::getMax).max(Double::compare).get();
final Double minGlob = Arrays.stream(rowResults).map(MinMaxResult::getMin).min(Double::compare).get();
System.out.println("Max is: " + maxGlob + " and min is: " + minGlob);
}
private static Double[][] generateData(int rows, int cols) {
final Double[][] randomMatrix = new Double[rows][cols];
final Random random = new Random();
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
randomMatrix[j][i] = random.nextDouble();
}
}
return randomMatrix;
}
private static class MinMaxResult {
private Double min;
private Double max;
public MinMaxResult(Double min, Double max) {
this.min = min;
this.max = max;
}
public Double getMin() {
return min;
}
public void setMin(Double min) {
this.min = min;
}
public Double getMax() {
return max;
}
public void setMax(Double max) {
this.max = max;
}
}
}