我试图实现一个Fork Join Pool,它将占用一个节点的子节点并同时探索它们。但是我认为我的fork join pool执行线程然后关闭得太快,导致线程停止执行?
到目前为止,我有这段代码:
主要方法:
while (!(pqOpen.IsEmpty()))
{
tempVertex = pqOpen.GetNextItem();
if (tempVertex.city == endLocation.city)
{
resetVertex();
return tempVertex;
}
else
{
ForkJoinPool forkJoinPool = new ForkJoinPool(tempVertex.neighbors.GetNoOfItems());
for (int i = 0; i < tempVertex.neighbors.GetNoOfItems(); i++) //for each neighbor of tempVertex
{
forkJoinPool.execute(new NeighbourThread(tempVertex, allVertices, routetype, pqOpen, i, endLocation));
}
forkJoinPool.shutdown();
}
}
return null;
}
这是我的课程:
public class NeighbourThread extends RecursiveAction {
Vertex tempVertex, endLocation;
VertexHashMap allVertices;
int routetype, i;
PriorityQueue pqOpen;
public NeighbourThread(Vertex tempVertex, VertexHashMap allVertices, int routetype, PriorityQueue pqOpen, int i, Vertex endLocation)
{
this.allVertices = allVertices;
this.routetype = routetype;
this.tempVertex = tempVertex;
this.pqOpen = pqOpen;
this.i = i;
this.endLocation = endLocation;
}
@Override
public void compute() {
Edge currentRoad = tempVertex.neighbors.GetItem(i);
Vertex vertexNeighbour = allVertices.GetValue(currentRoad.toid);
if (vertexNeighbour.inClosed)//
return null;
if ((!vertexNeighbour.inOpen) || temp_g_score < vertexNeighbour.getTentativeDistance())
{
vertexNeighbour.from = tempVertex;
vertexNeighbour.setTentativeDistance(temp_g_score);
// if neighbor isn't in open set, add it to open set
if (!vertexNeighbour.inOpen)
{
vertexNeighbour.inOpen = true;
pqOpen.AddItem(vertexNeighbour);
}
}
}
我已经删除了compute()中的大部分代码,因为我感觉它与问题无关。
我认为问题是forkJoinPool.shutdown()行在创建的线程完成执行之前执行。 在我循环回到while循环的顶部之前,有没有办法确保线程完成?
答案 0 :(得分:0)
你完全滥用这个框架。您没有进行Data Parallel处理。正如@erickson在上面的评论中所说,没有递归。
如果tempVertex.neighbors.GetNoOfItems()为1,000怎么办?您将创建1,000个线程,然后关闭框架;在while(!(pqOpen.IsEmpty()))等的下一次迭代中创建一个新框架。创建框架需要相当多的开销。创建线程需要更多的开销。
我不喜欢批评你的工作但不知道所有的要求我不能给你一个更好的设计(这将是建设性的批评。)
也许您应该查看具有线程池结构的阻塞队列。