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()
beyondbarrier.await()
--就像您在t.join()
@victororokin中显示的那样,我不知道如何检查await()的返回值
将帮助我检查是否有左边的部分。行
和n个线程
的值不是事先就知道的吗(在你开始提交任务之前)?是的,当然知道。那么,为什么你不能将代码添加到你的工作者run()
,这将检查wait()
是否返回0(最后到达,因此屏障被释放)如果为0,则工人将检查是否所有项目都已处理?