线程对象如何访问关联对象的方法?

时间:2016-02-05 13:06:56

标签: java multithreading matrix

我有一个随机整数的2d矩阵。我想在每一行中找到最小值和最大值(每行由不同的线程完成),然后我想整理结果并在所有矩阵中找到最小值和最大值。这是main中的代码:

Type2

2 个答案:

答案 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;
        }
    }
}