2

我想爲ThreadPoolExecutor使用有界隊列,但我想使用我的自定義RejectedExecutionExceptionHandler。我需要這樣做,以便我可以將拒絕的任務放到單獨的隊列中,並在一段時間後嘗試重新提交它們。
是一個自定義RejectedExecutionExceptionHandler解決我的問題?如果是,我該如何執行?
否則什麼是解決我的問題的最佳方法?ThreadPoolExecutor和RejectedExecutionExceptionHandler

+1

什麼使您使用無界隊列,而不是? – 2012-08-06 09:03:20

+0

@DuncanJones:確保我不會超載服務器 – Jim 2012-08-06 09:06:48

+0

您不會重載服務器,因爲您仍然必須定義最大數量的線程。我會在這裏停止發帖,因爲你在彼得的回答中有同樣的討論。 – 2012-08-06 09:11:58

回答

1

我會使用一個無界隊列,因爲這將排隊無法運行以供將來使用的任務。我會在你的情況下起訴Executors.newFixedThreadPool。您可能感興趣的這是什麼一樣

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

注:它採用了無界隊列。

恕我直言,處理問題最簡單/最好的方法是在當前線程中運行任務。

這確保所有任務都可以在沒有備用後臺線程的情況下使用當前線程及時執行。

new RejectedExecutionHandler() { 
    @Override 
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { 
     r.run(); 
    } 
} 
+0

你的意思是'新的ThreadPoolExecutor.CallerRunsPolicy()'? – Jim 2012-08-06 09:00:20

+0

如果池關閉,這將忽略任務,但您可以使用它。 – 2012-08-06 09:01:56

+0

這似乎是合理的,但我認爲它會減慢我的服務器。爲什麼不使用單獨的隊列?等一會兒,然後重新提交它們? – Jim 2012-08-06 09:01:57

2

你的情況,你想選擇哪個來,只有當有界隊列被填滿發揮飽和政策。通過調用setRejectedExecutionHandler()方法可以修改線程池執行程序的飽和策略。有四種類型的飽和政策:

  1. 中止(這實際上拋出一個異常,並允許呼叫者處理它)
  2. 丟棄(這實際上丟棄新提交的任務)
  3. 丟棄 - 最古老的(這放棄接下來要運行的任務並嘗試重新提交新任務)
  4. 調用者運行策略實現了某種形式的調節,既不放棄任務也不拋出異常,而是試圖通過以下方式減慢新任務的流量:將一些工作推回給調用者。因此,調用者線程忙於運行新任務,因此在此期間不能接受任何更多任務。

對於你的情況,我認爲CallerRunsPolicy()是最有意義的。這樣做:

executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());