首页 > 解决方案 > 如何为 Java Executor 的 runnable 提供参数?

问题描述

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

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 抱怨rowand colindeces 应该是最终的。但是我需要每个可运行对象都关心它自己的单元格,那么我怎样才能将这些值提供给可运行对象呢?

标签: javathreadpoolexecutor

解决方案


最好的解决方案是创建一个新的类来扩展可运行的并接受它需要使用的所有参数。在这种情况下,它是矩阵、随机种子 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.
        }
    }
}

推荐阅读