简体   繁体   English

Java线程池计时问题

[英]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: NeighbourThread类:

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). 我的想法是,它将基于currentItem.destinations.GetNoOfItems()创建所需的线程数量(因为它重用线程,我假设如果达到线程创建的限制,它将等待线程完成执行和重用它)。

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. 但是,我需要我的程序等待所有线程完成执行,然后再循环回到while循环。

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: 阅读有关.shutdown()的文档后,我认为这会停止将来对线程池的任何使用,我猜这就是为什么会出现此错误的原因:

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. 我正在尝试改善程序的执行时间,并且由于我目前正在对run()方法中的内容进行超过150万次调用,因此我认为这会有所帮助。

So is there anyway to get the program to wait until the threads have finished before continuing with the while loop? 那么,是否有必要让程序等待线程完成之后再继续while循环?

The easiest solution is to use the Future s to notify you when they have completed. 最简单的解决方案是使用Future来在完成时通知您。 Unfortunately, Java does not support listenable Future s out of the box, but you can use the Guava library to supplement you here. 不幸的是,Java不支持收听到的 Future出去了盒子的,但你可以使用番石榴库你在这里补充。

Guava adds the ListeneableFuture , which you can make using the Futures utility class: Guava添加了ListeneableFuture ,您可以使用Futures实用程序类进行创建:

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 . 另外, 如果您知道需要先运行多少项 ,则可以使用CountdownLatch进行此操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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