2015-04-29 3 views
0

Я пытаюсь внедрить пул Join Fork, который возьмет детей одного узла и исследует их одновременно. Тем не менее, я думаю, что мой пул соединяется с пулом, а затем отключается слишком быстро, заставляя потоки прекратить выполнение?Java Fork Join Pool Timing Issue

До сих пор у меня есть этот код:

Основной метод:

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); 
       } 
      } 
    } 

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

Я думаю, проблема в том, что строка forkJoinPool.shutdown() выполняется до того, как созданные потоки завершатся. Есть ли способ убедиться, что потоки закончены, прежде чем я вернусь назад к вершине цикла while?

+1

Я не читал слишком далеко в вашем коде, но, задавая вопрос, всегда полезно четко указать, в чем проблема. Я могу сказать, что ваша проблема заключается в том, что между выполнением ваших задач существует гонка, и когда вы закрываете, но не совсем уверены. Например, «Все задачи, которые я отправил, не исполняются» и т. Д. –

+0

Привет, Джон, я думаю, вы, возможно, не прочитали нижнюю часть моего сообщения, поэтому я отредактирую его и убедитесь, что в верхней части описание проблемы! – Craig

+0

Сторона примечания по качеству кода: назначение метода с общим термином (например, «вычисление») ... а затем выполнение многих разных вещей внутри этого единственного метода ... приводит к коду, который будет ** жестким ** для поддержания , См. Здесь: http://java.dzone.com/articles/single-responsibility – GhostCat

ответ

0

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

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

+0

"* Принимать * и выполнять все задачи ... но * не принимает * новые задачи" – erickson

0

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

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

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

Может быть, вы должны смотреть в очередь блокировки со структурой пула потоков.