[英]Java Thread Pool Timing Issue
我正在嘗試使用線程池執行一些代碼,但是在使其運行而不會出錯時遇到了一些麻煩。
這是我當前的結構:
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循環?
最簡單的解決方案是使用Future
來在完成時通知您。 不幸的是,Java不支持收聽到的 Future
出去了盒子的,但你可以使用番石榴庫你在這里補充。
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
進行此操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.