[英]How can I tell that threads in ThreadPoolExecutor are done?
我正在編寫代碼,以確保在提交結果之前,線程池中當前沒有任何線程正在運行(為避免丟失數據,我應該將其放入提交中)。 為此,我正在使用:
while (_executor.getActiveCount() > 0)
{
try
{
Thread.sleep(10); // milliseconds
}
catch (InterruptedException e)
{
// OK do nothing
}
}
但是一位同事在評論中指出,getActiveCount的文檔指出:
- 返回活躍線程的大概數量
- 執行任務。
因此,在池中仍然有活動線程的情況下,是否存在退出while循環的風險? 如果是這樣,等待我所有工作線程完成的正確方法是什么?
編輯:提供更多上下文 :這是一個聯機系統,其中包含執行程序服務的任務將無限期運行。 工作通過消息傳遞系統進入,放置在執行程序中的線程上,不需要任何同步,並且工作進入消息傳遞系統的另一個隊列。 我不想殺死執行程序以等待任務完成。
您可能要考慮使用CompletionService
( http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CompletionService.html )。
CompletionService
包裝ExecutorService
並在提交任務時返回Future
。 通過維護這些Future
的列表,您可以查看正在等待的作業是否已經完成。 它還具有其他優勢,因為您可以使用某些會計方法,因此可以讓其他人使用相同的ExecutorService
,
_executor.awaitTermination();
應該做的工作。 現在,它實際上不會等待線程關閉,而是會等待所有可用任務終止。
您還可以向線程池構造函數提供keepAliveTime
,以立即終止空閑線程:
ExecutorService executor = new ThreadPoolExecutor(0, 10, 0L /* keepAlive */,
TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
若要通知線程應清除並終止,請使用interrupt方法。 t.interrupt();
並且可以從catch塊打印或記錄錯誤日志。
當任務提交給執行者時,它們將返回Future,后者指示它們何時完成。 那是首選的使用機制。
您可以使用JDK ExecutorService關閉/ awaitTermination。
用例:需要在池線程完成后清除線程中的線程局部,這種清除可能需要很長時間(例如,連接關閉)。 之后,主線程才能繼續。
工作線程可以在某些集合中注冊自己。 為此,覆蓋start()
和run()
並將自定義線程工廠傳遞給ThreadPoolExecutor
:
class MyThreadFactory implements ThreadFactory {
@Override
public Thread newThread(final Runnable r) {
return new MyThread(r);
}
...
class Some {
void waitAllThreads() {
Thread worker;
while ((worker = workerThreads.poll()) != null) {
worker.join();
}
}
...
class MyThread extends Thread {
@Override
public synchronized void start() {
if (getState() == State.NEW) {
some.workerThreads.offer(this);
}
super.start();
}
@Override
public void run() {
try {
super.run();
} finally {
some.workerThreads.remove(this);
}
}
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.