【问题标题】:Java Thread Pool Timing IssueJava 线程池计时问题
【发布时间】:2015-04-29 21:25:29
【问题描述】:

我正在尝试使用线程池来执行一些代码,但是我无法让它在没有错误的情况下运行。

这是我目前的结构:

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 类:

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

我的想法是它将根据currentItem.destinations.GetNoOfItems()创建所需的线程数量(因为它重用线程,我假设如果它达到线程创建的限制,它将等待线程完成执行并重用它)。

一旦线程被分配,它会提交每个可运行的线程并启动它。

但是我需要我的程序在循环回while循环之前等待所有线程完成执行。

在阅读了关于 .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]

我正在尝试缩短程序的执行时间,因为我目前正在对 run() 方法中的内容进行超过 150 万次调用,我觉得这会有所帮助。

那么有没有办法让程序等到线程完成后再继续 while 循环?

【问题讨论】:

  • 在关机前使用 FutureTask 了解任务的状态。 javacodegeeks.com/2013/07/java-futuretask-example-program.html
  • 提示:ExecutorService#submit() 返回什么?
  • 拥有ExecutorService 的新实例有什么问题?
  • @Nambari 我现在看看那个链接!
  • @MattBall 如果完成则返回 null - 所以我可以存储它,如果它为 null 我可以继续 while 循环?

标签: java multithreading concurrency threadpool


【解决方案1】:

最简单的解决方案是使用Futures 在他们完成时通知您。不幸的是,Java 不支持 listenable Futures 开箱即用,但您可以在此处使用 Guava 库作为补充。

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

或者,您可以使用CountdownLatch 执行此操作如果您知道需要预先运行多少项目。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-02
    • 1970-01-01
    • 2016-11-13
    • 2011-02-27
    • 1970-01-01
    • 2017-07-08
    • 1970-01-01
    相关资源
    最近更新 更多