【问题标题】:Java: threading divided into blocks array - executor serviceJava:线程划分为块数组 - 执行器服务
【发布时间】:2021-01-28 12:39:04
【问题描述】:

我正在创建一个程序来模拟步骤中计算两个数组的值(它们是从一开始就初始化的,我没有放在这里)。我想用线程和 ExecutorService 来做。我将数组分成块,我希望这些块的值由线程计算,一个块=一个线程。这两个数组 - X 和 Y - 相互取值(如您在 run() 中所见),我希望先计算 X,然后计算 Y,所以我制作了两个单独的可运行对象:

public static class CountX implements Runnable {
    private int start;
    private int end;
    private CountDownLatch cdl;
    public CountX(int s, int e, CountDownLatch c) {
        this.start = s;
        this.end = e;
        this.cdl = c;
    }
    public void run() {
        for (int i = start + 1; i < end - 1; i++) {
            x[i] = x[i] - (y[i-1] - 2 * y[i] + y[i+1]) + y[i];
        }
        cdl.countDown();            
    }
}

CountY 也是如此。我想向它提供每个块的值的开始和结束位置的信息。

简而言之,这是我的主要问题,这是我的主要问题:

int NN = 400; //length of X and Y
int threads = 8;
int block_size = (int) NN/threads;

final ExecutorService executor_X = Executors.newFixedThreadPool(threads); 
final ExecutorService executor_Y = Executors.newFixedThreadPool(threads);
CountDownLatch cdl = new CountDownLatch(threads);
    
CountX[] runnables_X = new CountX[threads];
CountY[] runnables_Y = new CountY[threads];

for (int r = 0; r < threads; r++) {
        runnables_X[r] = new CountX((r*block_size), ((r+1)*block_size), cdl); 
}
for (int r = 0; r < threads; r++) {
        runnables_Y[r] = new CountY((r*block_size), ((r+1)*block_size), cdl);
}


int sim_steps = 4000;
for(int m = 0; m < sim_steps; m++) {
    for (int e = 0; e < threads; e++) {
        executor_X.execute(runnables_X[e]);
    }
    for (int e = 0; e < threads; e++) {
        executor_Y.execute(runnables_Y[e]);
    }
}
executor_X.shutdown();
executor_Y.shutdown();

我从这个程序中得到了错误的数组 X 和 Y 值,因为我也是在没有线程的情况下完成的。 这里需要 CountDownLatch 吗?我应该在每个 m (sim_step) 循环中执行runnables_X[r] = new CountX((r*block_size), ((r+1)*block_size), cdl); 的循环吗?或者也许我应该以不同的方式使用 ExecutorService?我尝试了很多选项,但结果仍然是错误的。 提前谢谢!

【问题讨论】:

    标签: java multithreading executorservice


    【解决方案1】:

    你的方法是我可能不会用于这项任务的方法。

    您可以使用引用和 Runnables,但在您的情况下,Callable 可能是更好的选择。使用 Callable,您只需给它一个数组并让它计算一个部分值,如果可能的话并等待Futures。对我来说,你实际上想要计算什么并不是很清楚,因此我在这里盲目猜测。

    您不需要CountDownLatch 也不需要两个ExecutorServices - 一个 EXS 就足够了。

    如果您真的想为此使用Runnable,您应该使用并发列表、原子变量、volatile 或锁来实现某种同步。

    【讨论】:

    • 我正在计算 X 和 Y 的值,它们在 runnables 的 run() 中
    • 这有点宽泛。您只分享了与 y 的值相关的 x 计算。当 x 依赖于先计算 y 时,应先计算 y,等待结果再计算 x。此外,数组不是线程安全的。
    • y 也依赖于 x,就像 x 依赖于 y。还是非常感谢!我会在这里尝试使用 Callable。
    猜你喜欢
    • 1970-01-01
    • 2020-05-18
    • 1970-01-01
    • 2017-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-08
    相关资源
    最近更新 更多