Проблема времени объединения пула Java Fork

Я пытаюсь реализовать 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?

2 ответа

Держу пари, что вам нужно awaitTermination на ForkJoinPool после выключения. Пул должен принимать и выполнять все задачи, пока он находится в shutdown фаза, но не будет принимать новые задачи

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

Вы совершенно неправильно используете эту структуру. Вы не выполняете параллельную обработку данных. Как сказал @erickson в приведенных выше комментариях, рекурсии нет.

Что если tempVertex.neighbors.GetNoOfItems() равен 1000? Вы собираетесь создать 1000 потоков, а затем закрыть фреймворк; создайте новый фреймворк на следующей итерации while (!(pqOpen.IsEmpty())) и т. д. Создание фреймворка требует довольно много времени. Создание потоков занимает еще больше накладных расходов.

Я не люблю критиковать вашу работу, но, не зная всех требований, я не могу дать вам лучший дизайн (это будет конструктивная критика).

Возможно, вам следует заглянуть в очередь блокировки со структурой пула потоков.

Другие вопросы по тегам