【问题标题】:How to provide arguments for the runnable of a Java Executor? [duplicate]如何为 Java Executor 的 runnable 提供参数? [复制]
【发布时间】:2020-10-17 02:42:19
【问题描述】:

我想用随机整数同时填充nRows * nCols 矩阵的单元格。这里的runnable只是一个setter,它将矩阵的一个单元格设置为一个随机整数。

public class ConcurrentMatrix {

    private int nRows;
    private int nCols;
    private int[][] matrix = new int[nRows][nCols];

    private MyConcurrentMatrixFiller myConcurrentMatrixFiller;

    public ConcurrentMatrix(int nRows, int nCols, MyConcurrentMatrixFiller filler) {
        this.nRows = nRows;
        this.nCols = nCols;
        this.matrix = new int[nRows][nCols];
        Random r = new Random();
        for (int row=0; row<nRows; row++) {
            for (int col=0; col<nCols; col++) {
                Runnable runnable = new Runnable() {
                    public void run() {
                        matrix[row][col] = r.nextInt(100);
                    }
                };
                filler.execute(runnable); // non-blocking, just depositing runnable in queue.
            }
        }
    }
}

filler 启动线程池:

public class MyConcurrentMatrixFiller implements Executor {
    BlockingQueue<Runnable> channel = new LinkedBlockingQueue<>();

    @Override
    public void execute(Runnable command) {
        channel.offer(command);
    }

    public MyConcurrentMatrixFiller(int nthreads) {
        for (int i=0; i<nthreads; i++) {
            activate();
        }
    }

    private void activate() {
        new Thread(() -> {
            try {
                while (true) { channel.take().run(); }
            } catch (InterruptedException e) { }
        }).start();
    }   

    public static void main(String[] args) {
        MyConcurrentMatrixFiller filler = new MyConcurrentMatrixFiller(10);
        ConcurrentMatrix cm = new ConcurrentMatrix(10, 10, filler);
    }
}

但是,我的 IDE 抱怨 rowcol 索引应该是最终的。但是我需要每个 runnable 都关心它自己的单元格,那么我怎样才能将这些值提供给 runnable?

【问题讨论】:

  • 这是因为您正在创建一个捕获变量的匿名类。您可以简单地编写一个实现 Runnable 的类。或者,也许您可​​以在声明 Runnable 之前声明两个最终变量并分配它们 i,j,不确定。顺便提一句。对单个随机数使用线程似乎……矫枉过正。也许你想每行/每列做一次?
  • 您可以为这两行和 col 声明 final int 并将其传递给线程 final int myRow = row;找到 int myCol = col;矩阵[myRow][myCol]
  • 我确定我已经尝试过了..
  • 每行有一个线程很好......但它在 100x100 时死掉了......

标签: java threadpoolexecutor


【解决方案1】:

最好的解决方案是创建一个新的类来扩展可运行对象并接受它需要使用的所有参数。在这种情况下,它是矩阵、随机种子 r 和行和列。 在您的情况下,它看起来像这样:

你的新班级:

public class MyExecutor extends Runnable {
    private final int[][] matrix;
    private final Random r;
    private final int row;
    private final int col;
    public MyExecutor( int[][] matrix, Random r, int row, int col ) {
        this.matrix = matrix;
        this.r = r;
        this.row = row;
        this.col = col;
    }

    @Override
    public void run() {
        matrix[row][col] = r.nextInt(100);
    }
}

还有你的 ConcurrentMatrix:

public ConcurrentMatrix(int nRows, int nCols, MyConcurrentMatrixFiller filler) {
    this.nRows = nRows;
    this.nCols = nCols;
    this.matrix = new int[nRows][nCols];
    Random r = new Random();
    for (int row=0; row<nRows; row++) {
        for (int col=0; col<nCols; col++) {
            Runnable runnable = new MyExecutor( row, col );
            filler.execute(runnable); // non-blocking, just depositing runnable in queue.
        }
    }
}

【讨论】:

  • matrixr 不为新班级所知
  • 哦,对了,我错了。我应该先把它放到 IDE 中。
猜你喜欢
  • 2011-03-11
  • 1970-01-01
  • 2017-11-19
  • 2012-07-15
  • 2017-11-29
  • 2020-11-06
  • 1970-01-01
  • 1970-01-01
  • 2020-01-25
相关资源
最近更新 更多