簡體   English   中英

從(ExecutorService)CachedThreadPool捕獲異常

[英]Catching Exceptions from (ExecutorService) CachedThreadPool

我們正在使用通過ExecutorService#newCachedThreadPool創建的CachedThreadPool。 (Java 1.6)。 我們在代碼中的其他地方遇到錯誤:“無法創建新的本機線程”,我們已將其診斷為內存不足問題。 當這個問題發生時,我們調用submit(我們使用submit,而不是execute)的代碼塊會變慢。 我們懷疑ThreadPool在嘗試創建新線程來處理任務時遇到了“無法創建新的本機線程”的相同問題,但我們無法確定。

有沒有辦法從ExecutorService中捕獲異常? 為了100%明確,我不是在談論給予ExecutorService的任務,而是來自ExecutorService本身。

Executors.newCachedThreadPool創建一個ThreadPoolExecutor ,它具有無限的最大線程池大小(注意ThreadPoolExecutor構造函數的第二個參數):

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}

這意味着如果您提交的任務比消耗率更快,則將為每個新任務創建新線程,最終它將達到系統限制並且拋出“無法創建新的本機線程”異常。

要解決此問題,您需要更改ThreadPoolExecutor的配置:

  1. 使用合理的ThreadPoolExecutor。
  2. ThreadPoolExecutor用盡時,選擇適當的拒絕策略。

例如:

ExecutorService executorService = new ThreadPoolExecutor(5,200,
                          60L, TimeUnit.SECONDS,
                          new ArrayBlockingQueue(1000),
                          Executors.defaultThreadFactory(),
                          new ThreadPoolExecutor.CallerRunsPolicy());

請閱讀JavaDocs以獲取配置詳細信息。

您可以使用一個自定義類來實現Runnable,其中包含一組excpetions,如下所示:

public class MyRunnable implements Runnable {
    private List<Exception> exceptions;

    ...

    public void addException(Exception e) { ... }
    public void getExceptions(){ ... }
}

在所有runnables完成執行后,您可以檢查其中的異常,並在響應中拋出另一個異常。

暫無
暫無

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

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