簡體   English   中英

如果ExecutorService的隊列已滿,會發生什么

[英]What happens if ExecutorService's queue is full

我有一個高達TB的大文件,我的任務是逐行處理。 每一行應該花費5秒才能完成。 為了提高性能,我將進程分配給這樣的固定線程池

ExecutorService executor = Executors.newFixedThreadPool(5);     

while ((line = br.readLine()) != null) {
  Runnable worker = new WorkerThread(line);
  executor.execute(worker); 
}

我的問題是如果我通過執行如此多的任務來壓倒執行程序的隊列會發生什么。 它會拋棄StackOverflow嗎?

如果你的處理速度比你輸入的速度快,它會拋出一個OOM錯誤(gc開銷)。 您無法獲得StackOverflow因為堆棧不會發生太大變化。

@StinePike提出了一個很好的問題。 如果沒有更多線程處理隊列中的項目並且隊列已滿,則會發生RejectedExecutionException 在這種情況下, Executors.newFixedThreadPool(5);默認實現Executors.newFixedThreadPool(5); 將使用無界的LinkedBlockingQueue 你唯一的限制是記憶。

這可能是一個主題,但是這個問題的一個選項是使用固定長度的阻塞隊列並使用ThreadPoolExecutor.CallerRunPolicy()。 這樣,如果消費者不夠快(因此隊列正在填滿),那么將使用調用者線程(生產者)來運行任務本身。 我們可以像下面這樣初始化一個Executor:

executorService = new ThreadPoolExecutor(DEFAULT_THREAD_COUNT,
        DEFAULT_THREAD_COUNT, 2, TimeUnit.MINUTES,
        new ArrayBlockingQueue<Runnable>(DEFAULT_QUEUE_LENGTH),
        new ThreadPoolExecutor.CallerRunsPolicy());

來自API: “被拒絕任務的處理程序,它直接在execute方法的調用線程中運行被拒絕的任務,除非執行程序已被關閉,在這種情況下,任務將被丟棄。”

在檢查Executors.newFiexedThreadPool實現時,

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

任務將被拋入LinkedBlockingQueue並等待線程執行。 如果有太多任務在等待,它可能會拋出OutOfMemory而不是StackOverflow

您將獲得OutOfMemoryError,因為newFixedThreadPool使用無界阻塞隊列。 您可以通過使用有界隊列實例化ThreadPoolExecutor來避免這種情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM