简体   繁体   中英

Java Thread Pool Timing Issue

I'm trying to use a thread pool to execute some code, however I'm having some trouble getting it to run without errors.

Here is my current structure:

while (!(queue.IsEmpty())) 
{ 
    currentItem= queue.GetNextItem();
    for (int i = 0; i < currentItem.destinations.GetNoOfItems(); i++) //for each neighbor of currentItem
    {                    
         threadPool.submit(new NeighbourThread(currentItem, allVertices, routetype, pqOpen, i, endLocation));
    }
    //threadPool.shutdown();
}

NeighbourThread class:

public class NeighbourThread implements Runnable {
    Vertex tempVertex, endLocation;
    VertexHashMap allVertices;
    int routetype, i;
    PriorityQueue pqOpen;   

    public NeighbourThread(Vertex tempVertex, VertexHashMap allVertices, int routetype, PriorityQueue pqOpen, int i, Vertex endLocation)
    {
        ...variables
    }
    @Override
    public void run() {
          ...execution code
          }
    }

My idea is that it will create the amount of threads required based on currentItem.destinations.GetNoOfItems() (as it reuses threads, I'm assuming if it reaches the limit on thread creation it will wait for a thread to finish execution and reuse it).

Once the threads have been allocated, it will submit each runnable to the thread and start it.

However I need my program to wait for all threads to finish execution before it loops back to the while loop.

After reading the documentation on .shutdown(), I think that stops any future use of the threadpool, which I'm guessing is why I get this error:

Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@3d4eac69 rejected from java.util.concurrent.ThreadPoolExecutor@42a57993[Shutting down, pool size = 3, active threads = 1, queued tasks = 0, completed tasks = 3]

I'm trying to improve execution time on my program and as I'm currently doing over 1.5 million invocations of what will be in the run() method, I feel this will help.

So is there anyway to get the program to wait until the threads have finished before continuing with the while loop?

The easiest solution is to use the Future s to notify you when they have completed. Unfortunately, Java does not support listenable Future s out of the box, but you can use the Guava library to supplement you here.

Guava adds the ListeneableFuture , which you can make using the Futures utility class:

ListeningExecutorService executor = MoreExecutors.listeningDecorator(threadPool);
// Collect the futures as you add them to the threadpool
List<ListenableFuture<?>> futures = new ArrayList<>();

while (! queue.IsEmpty()) 
{ 
    currentItem = queue.GetNextItem();

    for (int i = 0; i < currentItem.destinations.GetNoOfItems(); i++)
    {
        // NeighbourThread should be a Runnable and not a Thread!
        futures.add(executor.submit(new NeighbourThread(currentItem, allVertices, routetype, pqOpen, i, endLocation)));
    }
}

// Get notified when they're all done (doesn't imply success!)
Futures.allAsList(futures)).addListener(new Runnable() {

    // When this callback is executed, then everything has finished

}, MoreExecutors.directExecutor());

Alternatively, you could do this with a CountdownLatch if you know how many items you need to run upfront .

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