Проблема времени объединения пула 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())) и т. д. Создание фреймворка требует довольно много времени. Создание потоков занимает еще больше накладных расходов.
Я не люблю критиковать вашу работу, но, не зная всех требований, я не могу дать вам лучший дизайн (это будет конструктивная критика).
Возможно, вам следует заглянуть в очередь блокировки со структурой пула потоков.