0

我正在尝试实现一个 Fork Join Pool,它将带一个节点的子节点并同时探索它们。但是我认为我的 fork 连接池执行线程然后关闭太快,导致线程停止执行?

到目前为止,我有这个代码:

主要方法:

    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 循环的顶部之前完成?

4

2 回答 2

0

你完全在滥用这个框架。您没有进行数据并行处理。正如@erickson 在上述评论中所说,没有递归。

如果 tempVertex.neighbors.GetNoOfItems() 为 1,000 会怎样?您将创建 1,000 个线程,然后关闭框架;在 while (!(pqOpen.IsEmpty())) 等的下一次迭代中创建一个新框架。创建框架需要相当多的开销。创建线程需要更多的开销。

我不喜欢批评你的工作,但在不了解所有要求的情况下,我无法给你更好的设计(那将是建设性的批评。)

也许您应该研究具有线程池结构的阻塞队列。

于 2015-04-29T18:41:02.520 回答
0

我敢打赌,您需要awaitTermination在关闭后使用 ForkJoinPool。池应在其处于阶段时接受并执行所有任务,shutdown但不会接受新任务

forkJoinPool.awaitTermination(Integer.MAX_VALUE, TimeUnit.DAYS);

于 2015-04-29T15:30:27.440 回答