java - 在内部类中绕过 "final or effectively final"会给出非常随机的结果

标签 java lambda parallel-processing

我正在做一个编程类(class)项目,用于 400 行矩阵本身的矩阵乘法。我让它以顺序模式工作,该项目的目标是编写并行实现。

我有以下代码,当然,当我尝试引用内部类中的计数器 j 时,我收到一个关于 j 必须是“最终或有效最终”的错误。我发现这个解决方法使用最终数组,但更改第一个元素,但它给出了非常不可预测的结果,我本希望它从 0 计数到 399,但它以随机顺序吐出数字,然后重复很多数字,包括 399很多次。

有什么想法可以在内部类中使用递增计数器吗?目标是调用该方法来处理内部类中矩阵中每一行的矩阵乘法,因为我们应该拥有与矩阵中的行一样多的线程。感谢您的帮助!

代码如下:

private static double parallelMatrixMultiply()
{
    // use the existing arrays A and B, multiply them together
    // use the parallel approach
    // Create a fixed thread pool with maximum of three threads
    ExecutorService executor = Executors.newFixedThreadPool(numRows);

    final int[] counter = new int[]{0};

    // submit a new thread for each row in the matrix
    for (int j = 0; j < numRows ; j++)
    {
        // we can modify an element of an array that has been declared final
        counter[0] = j;
        // Submit runnable tasks to the executor
        executor.execute(new Runnable() {
            public void run() 
            {
                // set a task to multiply for each row here
                // will be replaced by a line to multiply each row of matrix
                System.out.println(counter[0]);
            }
        });
    }

    // Shut down the executor
    executor.shutdown();

    // return the value of the 1,1 position on zero notation
    //return matrixC.get(1).get(1); // return matrixC(1,1)
    return 42.0;
}

最佳答案

counter 是一个可以在回调方法中使用的最终变量。但数组的内容不是最终的,你会不断地改变它们。当 run() 方法被调用时,它将查看 counter[0] 在那一刻持有的任何内容,而不是在当您调用 execute 时的循环。

你最好这样做:

for (int j = 0; j < numRows ; j++) {
    final int finalj = j;
    executor.execute(new Runnable() {
        public void run() {
            System.out.println(finalj);
        }
    });
}

也就是说,将循环计数器的值分配给一个实际上是final的变量,以供回调方法使用。

关于java - 在内部类中绕过 "final or effectively final"会给出非常随机的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27126082/

相关文章:

Java lambda 交集两个列表并从结果中删除

python - Pandas lambda 函数无法识别 NaN

C# IS 运算符不能用于 lambda 表达式?

c# - 并行处理应用程序中的负载平衡

java - 无法从 https :maven-surefire-plugin:pom:2. maven.apache.org/maven2 传输 org.apache.maven.plugins ://repo. 22.2

java - React Native - java.lang.RuntimeException : SDK location not found. 在 local.properties 中使用 sdk.dir 定义位置

c - 如何从进程中打印某些内容而不与其他进程重叠?

c++ - OpenMP:无法并行化嵌套的 for 循环

java - 正弦的多项式逼近中的这些系数是如何确定的?

java - 这个java代码背后的逻辑是什么