Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 避免对骑自行车的人耍花招的想法_Java_Multithreading_Concurrency_Threadpool_Cyclicbarrier - Fatal编程技术网

Java 避免对骑自行车的人耍花招的想法

Java 避免对骑自行车的人耍花招的想法,java,multithreading,concurrency,threadpool,cyclicbarrier,Java,Multithreading,Concurrency,Threadpool,Cyclicbarrier,我用并行处理运行了一些测试,并制作了一个程序,给出一个整数矩阵,然后根据邻域重新计算每个位置的值 我需要一份矩阵的副本,这样就不会覆盖这些值,并在部分问题解决后使用CyclicBarrier合并结果: CyclicBarrier cyclic_barrier = new CyclicBarrier(n_tasks + 1, new Runnable() { public void run() { ParallelProcess.mergeResult(); } }

我用并行处理运行了一些测试,并制作了一个程序,给出一个整数矩阵,然后根据邻域重新计算每个位置的值

我需要一份矩阵的副本,这样就不会覆盖这些值,并在部分问题解决后使用
CyclicBarrier
合并结果:

CyclicBarrier cyclic_barrier = new CyclicBarrier(n_tasks + 1, new Runnable() {
    public void run() {
        ParallelProcess.mergeResult();
    }
});
ParallelProcess p = new ParallelProcess(cyclic_barrier, n_rows, r_cols); // init
每个任务都分配了矩阵的一部分:我将它按行等分。但是分区可能不精确,因此最后一行对应的一小段不会提交到线程池

示例:如果我有
16
行,并且
n_tasks=4
没有问题,那么所有4行都将提交到池中。但是,如果我有
18
,那么将提交前16个,而不是最后两个

所以如果这个案子发生了,我会强制提交。实际上,我并没有提交,因为我使用的是我创建的固定线程池,就像这样
ExecutorService e=Executors.newFixedThreadPool(n_tasks)
。由于池中的所有插槽都被占用,线程被屏障阻塞(
mybarrier.await()
run
方法中被调用),因此我无法将其提交到池中,所以我只使用了
Thread.start()

让我们开门见山吧。因为我需要考虑
CyclicBarrier
块剩余的可能性,所以参与方的数量必须增加1

但如果这件事没有发生,我就少了一方来触发障碍

我的解决方案是什么

if (lower_limit != n_rows) { // the remaining chunk to be processed
    Thread t = new Thread(new ParallelProcess(lower_limit, n_rows));
    t.start();
    t.join();
}
else {
    cyclic_barrier.await();
}
当我使用
循环障碍物时,我感觉自己在作弊。wait()
使用强制提升障碍物的技巧


有没有其他方法可以解决这个问题,这样我就不必做我正在做的事情了?

虽然这并不能回答您关于自行车承运人的问题,但我可以推荐您使用自行车吗?这确实能够包括参与方的数量,并且还允许您在相位跳闸时运行
mergeResult

因此,在执行异步计算之前,只需
注册
。然后在该计算中,线程到达
相量器
。当所有线程到达时,它将推进该阶段,并可以在advance上调用重写的方法

来文:

ParallelProcess process = new ParallelProcess(lower_limit, n_rows));
phaser.register();
executor.submit(process);
处理器

public void run(){
   //do stuff
   phaser.arrive();
}
移相器

Phaser phaser = new Phaser(){
    protected boolean onAdvance(int phase, int registeredParties) {
        ParallelProcess.mergeResult(); 
        return true;
    }
}

关于这一点:在最后到达屏障的工作人员中(通过
barrier.await()
返回的值进行检查),您可以检查是否还有要继续的项目。如果是,工作人员可以提交新任务来处理遗留项目。也许,您仍然需要在
mergeResult()
beyond
barrier.await()
--就像您在
t.join()
@victororokin中显示的那样,我不知道如何检查
await()的返回值
将帮助我检查是否有左边的部分。
n个线程
的值不是事先就知道的吗(在你开始提交任务之前)?是的,当然知道。那么,为什么你不能将代码添加到你的工作者
run()
,这将检查
wait()
是否返回0(最后到达,因此屏障被释放)如果为0,则工人将检查是否所有项目都已处理?