简体   繁体   中英

Java Fork Join Pool Timing Issue

I'm trying to implement a Fork Join Pool what will take the children of one node and explore them concurrently. However I think that my fork join pool executes the threads and then shuts down too quickly, causing the threads to stop executing?

So far I have this code:

Main method:

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

This is my class that it runs:

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

I've removed majority of the code within compute() as I don't feel it's relevant to the problem.

I think the problem is that the forkJoinPool.shutdown() line gets executed before the threads that have been created have finished executing. Is there any way to ensure that the threads are finished before I loop back round to the top of the while loop?

I would bet you need to awaitTermination on the ForkJoinPool after shutting down. The pool should accept and execute all tasks while it is in shutdown phase but won't accept new tasks

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

You are totally misusing this framework. You are not doing Data Parallel processing. As @erickson said in the above comments, there is no recursion.

What if tempVertex.neighbors.GetNoOfItems() is 1,000? You are going to create 1,000 threads and then shut down the framework; create a new framework on the next iteration of while (!(pqOpen.IsEmpty())), etc. Creating the framework takes quite a bit of overhead. Creating threads takes even more overhead.

I don't like criticizing your work but without knowing all the requirements I cannot give you a better design (that would be constructive criticism.)

Perhaps you should look into a blocking queue with thread pool structure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM