2015-04-29 77 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做到這一點。