當 Executor 已經關閉,並且 Executor 將有限邊界用於最大線程和工作隊列容量,且已經飽和時,在方法 execute(java.lang.Runnable) 中提交的新任務將被拒絕。在以上兩種情況下,execute 方法都將調用其 RejectedExecutionHandler 的 RejectedExecutionHandler.rejectedExecution(java.lang.Runnable, java.util.concurrent.ThreadPoolExecutor) 方法。下面提供了四種預定義的處理常式策略:
A. 在預設的 ThreadPoolExecutor.AbortPolicy 中,處理常式遭到拒絕將拋出運行時 RejectedExecutionException。
B. 在 ThreadPoolExecutor.CallerRunsPolicy 中,線程調用運行該任務的 execute 本身。此策略提供簡單的反饋控制機制,能夠減緩新任務的提交速度。
C. 在 ThreadPoolExecutor.DiscardPolicy 中,不能執行的任務將被刪除。
D. 在 ThreadPoolExecutor.DiscardOldestPolicy 中,如果執行程式尚未關閉,則位於工作隊列頭部的任務將被刪除,然後重試執行程式(如果再次失敗,則重複此過程)。
定義和使用其他種類的 RejectedExecutionHandler 類也是可能的,但這樣做需要非常小心,尤其是當策略僅用於特定容量或排隊策略時。
掛鈎方法
此類提供 protected 可重寫的 beforeExecute(java.lang.Thread, java.lang.Runnable) 和 afterExecute(java.lang.Runnable, java.lang.Throwable) 方法,這兩種方法分別在執行每個任務之前和之後調用。它們可用於操縱執行環境;例如,重新初始化 ThreadLocal、搜集統計資訊或添加日誌條目。此外,還可以重寫方法 terminated() 來執行 Executor 完全終止後需要完成的所有特殊處理。
如果掛鈎或回調方法拋出異常,則內部輔助線程將依次失敗並突然終止。
隊列維護
方法 getQueue() 允許出於監控和調試目的而訪問工作隊列。強烈反對出於其他任何目的而使用此方法。remove(java.lang.Runnable) 和 purge() 這兩種方法可用於在取消大量已排隊任務時協助進行儲存回收。
一、例子
建立 TestThreadPool 類:
建立 ThreadPoolTask類:
執行結果:
建立任務並提交到線程池中:task@ 1
開始執行任務:task@ 1
建立任務並提交到線程池中:task@ 2
開始執行任務:task@ 2
建立任務並提交到線程池中:task@ 3
建立任務並提交到線程池中:task@ 4
開始執行任務:task@ 3
建立任務並提交到線程池中:task@ 5
開始執行任務:task@ 4
建立任務並提交到線程池中:task@ 6
建立任務並提交到線程池中:task@ 7
建立任務並提交到線程池中:task@ 8
開始執行任務:task@ 5
開始執行任務:task@ 6
建立任務並提交到線程池中:task@ 9
開始執行任務:task@ 7
建立任務並提交到線程池中:task@ 10
開始執行任務:task@ 8
開始執行任務:task@ 9
開始執行任務:task@ 10
from :http://blog.csdn.net/yangdengfeng2003/archive/2009/04/01/4042252.aspx
view plaincopy to clipboardprint?
- import java.io.Serializable;
-
- public class ThreadPoolTask implements Runnable, Serializable {
-
- private Object attachData;
-
- ThreadPoolTask(Object tasks) {
- this.attachData = tasks;
- }
-
- public void run() {
-
- System.out.println("開始執行任務:" + attachData);
-
- attachData = null;
- }
-
- public Object getTask() {
- return this.attachData;
- }
- }
import java.io.Serializable;</p><p>public class ThreadPoolTask implements Runnable, Serializable {</p><p>private Object attachData;</p><p>ThreadPoolTask(Object tasks) {<br />this.attachData = tasks;<br />}</p><p>public void run() {</p><p>System.out.println("開始執行任務:" + attachData);</p><p>attachData = null;<br />}</p><p>public Object getTask() {<br />return this.attachData;<br />}<br />}
view plaincopy to clipboardprint?
- import java.util.concurrent.ArrayBlockingQueue;
- import java.util.concurrent.ThreadPoolExecutor;
- import java.util.concurrent.TimeUnit;
-
- public class TestThreadPool {
-
- private static int produceTaskSleepTime = 2;
-
- private static int produceTaskMaxNumber = 10;
-
- public static void main(String[] args) {
-
- // 構造一個線程池
- ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 4, 3,
- TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3),
- new ThreadPoolExecutor.DiscardOldestPolicy());
-
- for (int i = 1; i <= produceTaskMaxNumber; i++) {
- try {
- String task = "task@ " + i;
- System.out.println("建立任務並提交到線程池中:" + task);
- threadPool.execute(new ThreadPoolTask(task));
-
- Thread.sleep(produceTaskSleepTime);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
import java.util.concurrent.ArrayBlockingQueue;<br />import java.util.concurrent.ThreadPoolExecutor;<br />import java.util.concurrent.TimeUnit;</p><p>public class TestThreadPool {</p><p>private static int produceTaskSleepTime = 2;</p><p>private static int produceTaskMaxNumber = 10;</p><p>public static void main(String[] args) {</p><p>// 構造一個線程池<br />ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 4, 3,<br />TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3),<br />new ThreadPoolExecutor.DiscardOldestPolicy());</p><p>for (int i = 1; i <= produceTaskMaxNumber; i++) {<br />try {<br />String task = "task@ " + i;<br />System.out.println("建立任務並提交到線程池中:" + task);<br />threadPool.execute(new ThreadPoolTask(task));</p><p>Thread.sleep(produceTaskSleepTime);<br />} catch (Exception e) {<br />e.printStackTrace();<br />}<br />}<br />}<br />}