【问题标题】:Getting around "final or effectively final" in inner classes gives very random results在内部类中绕过“最终或有效最终”会产生非常随机的结果
【发布时间】:2014-11-25 11:56:12
【问题描述】:

我正在为 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;
}

【问题讨论】:

  • 我搜索了,基于并行/线程找不到这个问题,很快就回去睡觉了,谢谢!

标签: java lambda parallel-processing


【解决方案1】:

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);
        }
    });
}

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

【讨论】:

  • 太棒了,它有效,它不会按顺序打印出数字,但在这种情况下是不相关的。对于似乎已删除的其他答案,我将研究 AtomicInteger 但我将在允许后尽快选择正确的答案。谢谢!!!!!!
  • 我删除的答案与您将在执行程序任务更改计数器的假设有关。如果您只需要每个任务的不可变值,那么这个答案是合适的。
猜你喜欢
  • 2017-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-13
  • 2015-01-25
相关资源
最近更新 更多