2015-04-29 50 views
0

我正在尝试使用线程池来执行一些代码,但是我在运行时遇到了一些麻烦而没有发生错误。Java线程池时序问题

这是我目前的结构:

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 [email protected] rejected from [email protected][Shutting down, pool size = 3, active threads = 1, queued tasks = 0, completed tasks = 3] 

我试图改善执行时间在我的程序上,因为我目前正在执行超过150万次run()方法的调用,我感觉这会有所帮助。

那么无论如何要让程序等到线程结束之后再继续while循环呢?

+0

在关机前使用FutureTask了解任务的状态。 http://www.javacodegeeks.com/2013/07/java-futuretask-example-program.html – kosa

+0

提示:ExecutorService#submit()'返回什么? –

+0

有一个新的ExecutorService实例有什么问题? –

回答

0

最简单的解决方案是使用Future来完成时通知您。不幸的是,Java不支持Future开箱即用,但您可以使用番石榴图书馆来补充您在这里。

番石榴添加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做到这一点。