2014-09-05 145 views
1

我們正在編寫一個應用程序,它使用ThreadPoolExecutor的自定義擴展來處理一堆Runnable s。在開發應用程序時,我們遇到了在Runnable類中發生的OutOfMemoryError。但是,與我們預期的afterExecute()不同,ThreadPoolExecutor只是繼續運輸。ThreadPoolExecutor忽略錯誤(OutOfMemoryError)

我已經將代碼削減到一個小的,可重複的應用程序。

ThreadPoolTest.java:

package org.codechimp.threadpool; 

import java.util.concurrent.LinkedBlockingQueue; 
import java.util.concurrent.ThreadPoolExecutor; 
import java.util.concurrent.TimeUnit; 

public class ThreadPoolTest { 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     LinkedBlockingQueue<Runnable> threadQueue = new LinkedBlockingQueue<Runnable>(); 
     ThreadPoolExecutor executor = new MyThreadPoolExecutor(10, Integer.MAX_VALUE, 2000, TimeUnit.MILLISECONDS, threadQueue); 

     // Create a bunch of Runnables now... 
     for (int i = 0; i < 10000; i++) { 
      executor.execute(new MyRunnable(i)); 
      if (i % 100 == 0) { 
       System.out.println("Queued " + i + " Runnables"); 
      } 
      if (i % 1000 == 0) { 
       try { 
        Thread.sleep(1); 
       } catch (InterruptedException ignored) { } 
      } 
     } 
     System.out.println("Done queing the Runnables."); 

     while (!executor.isTerminated() && !executor.isTerminating() && executor.getQueue().size() > 0) { 
      System.out.println(executor.getQueue().size() + " Runnables in the queue."); 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException ignored) { } 
     } 
     System.out.println("Runnable queue has stopped processing."); 

     executor.shutdown(); 
     try { 
      executor.awaitTermination(10, TimeUnit.MINUTES); 
     } catch (InterruptedException ignored) { } 
     System.out.println("Shutdown completed...exiting"); 
    } 
} 

MyThreadPoolExecutor.java:

package org.codechimp.threadpool; 

import java.util.concurrent.BlockingQueue; 
import java.util.concurrent.RejectedExecutionHandler; 
import java.util.concurrent.ThreadFactory; 
import java.util.concurrent.ThreadPoolExecutor; 
import java.util.concurrent.TimeUnit; 

public class MyThreadPoolExecutor extends ThreadPoolExecutor { 
    public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, 
      long keepAliveTime, TimeUnit unit, 
      BlockingQueue<Runnable> workQueue, 
      RejectedExecutionHandler handler) { 
     super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler); 
    } 

    public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, 
      long keepAliveTime, TimeUnit unit, 
      BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, 
      RejectedExecutionHandler handler) { 
     super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, 
       threadFactory, handler); 
    } 

    public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, 
      long keepAliveTime, TimeUnit unit, 
      BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) { 
     super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, 
       threadFactory); 
    } 

    public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, 
      long keepAliveTime, TimeUnit unit, 
      BlockingQueue<Runnable> workQueue) { 
     super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); 
    } 

    @Override 
    protected void afterExecute(Runnable r, Throwable t) { 
     if (t != null) { 
      System.out.println("We got an error: " + t); 
      int remaining = this.shutdownNow().size(); 
      System.out.println(remaining + " Runnables left in the queue"); 
     } 
    } 
} 

MyRunnable.java

package org.codechimp.threadpool; 

import org.apache.commons.lang.math.RandomUtils; 

public class MyRunnable implements Runnable { 
    private int runnableNumber; 
    private int counter = 0; 

    public MyRunnable(int number) { 
     this.runnableNumber = number; 
    } 

    /** 
    * Simple runnable that generates an OutOfMemoryError after the 1000th loop 
    */ 
    public void run() { 
     while (counter < 1000) { 
      counter++; 
      if (counter % 100 == 0) { 
       System.out.println("\tRunnable " + this.runnableNumber + " reached " + this.counter + "."); 
      } 

      if (this.runnableNumber == 15 && this.counter % 200 == 0) { 
       throw new OutOfMemoryError("This is a test!"); 
      } 

      int wait = RandomUtils.nextInt(100); 
      if (wait > 0) { 
       try { 
        //System.out.println("\tRunnable " + this.runnableNumber + " waiting " + wait + "."); 
        Thread.sleep(wait); 
       } catch (InterruptedException e) { 
        throw new RuntimeException("Thread.sleep() failed", e); 
       } 
      } 
     } 
    } 
} 

這是一個超級簡單的例子,將創造MyRunnable S的10K進入MyThreadPoolExectuor,打印出一些狀態信息作爲計數器i現象越來越多。第16次可運行(數字15,從0開始計數)將在第200次增量時拋出OutOfMemoryErrorMyThreadPoolExecutorafterExecute()將打印一條消息,如果它獲得Throwable。當我在Java 6和Java 7下運行它時,它從不打印此消息。

我們如何讓應用程序保全在所有Throwable s?我們真的想在這一點上終止事情。

更新/編輯:

我更新這是似乎有一些混亂,以什麼我問。 我知道錯誤被打印出來。問題不在於ThreadPoolExecutor未打印OutOfMemoryError,問題是,正如標題和我在最後詢問的問題中所述,afterExecute()未被調用Error s。由於OutOfMemoryErrorError的子類,這意味着當發生一個我有沒有方法停止代碼。

再次,請閱讀代碼試圖做的事情。當然,它試圖「處理」錯誤。它實際上試圖通過呼籲shutdownNow()停止ThreadPoolExecutor。但是,由於生成的Error以某種方式被抑制,所以該位代碼未被執行。結果,應用程序只是一直在徘徊,而忽略了它將OOME噴到整個地方的事實。

同樣,問題:

How do I detect a Runnable has recieved an Error (OutOfMemoryError or other) and terminate the ThreadPoolExecutor so the app will simply stop in it's tracks?

+0

我沒有運行在Java中jdk1.7.0_40你的代碼,並得到這個錯誤消息 >我們得到了一個錯誤:java.lang.OutOfMemoryError:這是一個測試! – Maas 2014-09-05 14:26:39

+0

http://stackoverflow.com/questions/511013/how-to-handle-outofmemoryerror-in-java,http://stackoverflow.com/questions/37335/how-to-deal-with-java-lang-outofmemoryerror -java堆空間誤差-64MB堆。底線:你不應該處理OutOfMemoryError,你應該防止它發生 – jny 2014-09-05 14:31:53

+0

適用於我..我看到錯誤。 – 2014-09-05 14:42:44

回答

-1

我並運行你的代碼,這裏是我的發現。一個任務中的錯誤對其他人來說不是封鎖。在下面的輸出中,第16個任務後會拋出錯誤,但程序不會終止並且其他任務成功執行。只有在執行第1000個任務後,纔會調用afterExecute方法。 您可能希望在每個任務完成後調用afterExecute。但事實並非如此。看起來像afterExecute方法不是在任務級別拋出,而是在線程池級別拋出。

我修改了afterExecute只是爲了確認其獲取調用

@Override 
    protected void afterExecute(Runnable r, Throwable t) { 
     if (t != null) { 
      System.out.println("We got an error: " + t); 
      int remaining = this.shutdownNow().size(); 
      System.out.println(remaining + " Runnables left in the queue"); 
     }else{ 
      System.out.println("t is null"); 
      if(r!=null){ 
       System.out.println(r.toString() +" after execute"); 
      }else{ 
       System.out.println("r is null"); 
      } 
     } 
    } 

控制檯輸出的代碼片段,其中OOM錯誤:

Queued 0 Runnables 
Queued 100 Runnables 
Queued 200 Runnables 
Queued 300 Runnables 
Queued 400 Runnables 
Queued 500 Runnables 
Queued 600 Runnables 
Queued 700 Runnables 
Queued 800 Runnables 
Queued 900 Runnables 
Queued 1000 Runnables 
Queued 1100 Runnables 
Queued 1200 Runnables 
Queued 1300 Runnables 
Queued 1400 Runnables 
Queued 1500 Runnables 
Queued 1600 Runnables 
Queued 1700 Runnables 
Queued 1800 Runnables 
Queued 1900 Runnables 
Queued 2000 Runnables 
Queued 2100 Runnables 
Queued 2200 Runnables 
Queued 2300 Runnables 
Queued 2400 Runnables 
Queued 2500 Runnables 
Queued 2600 Runnables 
Queued 2700 Runnables 
Queued 2800 Runnables 
Queued 2900 Runnables 
Queued 3000 Runnables 
Queued 3100 Runnables 
Queued 3200 Runnables 
Queued 3300 Runnables 
Queued 3400 Runnables 
Queued 3500 Runnables 
Queued 3600 Runnables 
Queued 3700 Runnables 
Queued 3800 Runnables 
Queued 3900 Runnables 
Queued 4000 Runnables 
Queued 4100 Runnables 
Queued 4200 Runnables 
Queued 4300 Runnables 
Queued 4400 Runnables 
Queued 4500 Runnables 
Queued 4600 Runnables 
Queued 4700 Runnables 
Queued 4800 Runnables 
Queued 4900 Runnables 
Queued 5000 Runnables 
Queued 5100 Runnables 
Queued 5200 Runnables 
Queued 5300 Runnables 
Queued 5400 Runnables 
Queued 5500 Runnables 
Queued 5600 Runnables 
Queued 5700 Runnables 
Queued 5800 Runnables 
Queued 5900 Runnables 
Queued 6000 Runnables 
Queued 6100 Runnables 
Queued 6200 Runnables 
Queued 6300 Runnables 
Queued 6400 Runnables 
Queued 6500 Runnables 
Queued 6600 Runnables 
Queued 6700 Runnables 
Queued 6800 Runnables 
Queued 6900 Runnables 
Queued 7000 Runnables 
Queued 7100 Runnables 
Queued 7200 Runnables 
Queued 7300 Runnables 
Queued 7400 Runnables 
Queued 7500 Runnables 
Queued 7600 Runnables 
Queued 7700 Runnables 
Queued 7800 Runnables 
Queued 7900 Runnables 
Queued 8000 Runnables 
Queued 8100 Runnables 
Queued 8200 Runnables 
Queued 8300 Runnables 
Queued 8400 Runnables 
Queued 8500 Runnables 
Queued 8600 Runnables 
Queued 8700 Runnables 
Queued 8800 Runnables 
Queued 8900 Runnables 
Queued 9000 Runnables 
Queued 9100 Runnables 
Queued 9200 Runnables 
Queued 9300 Runnables 
Queued 9400 Runnables 
Queued 9500 Runnables 
Queued 9600 Runnables 
Queued 9700 Runnables 
Queued 9800 Runnables 
Queued 9900 Runnables 
Done queing the Runnables. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
    Runnable 0 reached 100. 
    Runnable 7 reached 100. 
    Runnable 8 reached 100. 
    Runnable 9 reached 100. 
    Runnable 5 reached 100. 
    Runnable 1 reached 100. 
    Runnable 6 reached 100. 
    Runnable 4 reached 100. 
    Runnable 2 reached 100. 
9990 Runnables in the queue. 
    Runnable 3 reached 100. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
    Runnable 0 reached 200. 
    Runnable 7 reached 200. 
    Runnable 5 reached 200. 
    Runnable 9 reached 200. 
    Runnable 1 reached 200. 
    Runnable 6 reached 200. 
    Runnable 3 reached 200. 
    Runnable 4 reached 200. 
    Runnable 8 reached 200. 
9990 Runnables in the queue. 
    Runnable 2 reached 200. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
    Runnable 7 reached 300. 
    Runnable 1 reached 300. 
    Runnable 0 reached 300. 
    Runnable 5 reached 300. 
    Runnable 4 reached 300. 
    Runnable 3 reached 300. 
    Runnable 8 reached 300. 
    Runnable 6 reached 300. 
9990 Runnables in the queue. 
    Runnable 9 reached 300. 
    Runnable 2 reached 300. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
    Runnable 7 reached 400. 
    Runnable 1 reached 400. 
    Runnable 0 reached 400. 
    Runnable 3 reached 400. 
    Runnable 5 reached 400. 
    Runnable 8 reached 400. 
    Runnable 9 reached 400. 
9990 Runnables in the queue. 
    Runnable 6 reached 400. 
    Runnable 4 reached 400. 
    Runnable 2 reached 400. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
    Runnable 1 reached 500. 
9990 Runnables in the queue. 
    Runnable 7 reached 500. 
    Runnable 0 reached 500. 
    Runnable 3 reached 500. 
    Runnable 6 reached 500. 
9990 Runnables in the queue. 
    Runnable 5 reached 500. 
    Runnable 4 reached 500. 
    Runnable 8 reached 500. 
    Runnable 9 reached 500. 
    Runnable 2 reached 500. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
    Runnable 1 reached 600. 
9990 Runnables in the queue. 
    Runnable 7 reached 600. 
    Runnable 3 reached 600. 
    Runnable 8 reached 600. 
    Runnable 5 reached 600. 
    Runnable 0 reached 600. 
9990 Runnables in the queue. 
    Runnable 4 reached 600. 
    Runnable 2 reached 600. 
    Runnable 6 reached 600. 
    Runnable 9 reached 600. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
    Runnable 1 reached 700. 
    Runnable 8 reached 700. 
    Runnable 7 reached 700. 
    Runnable 5 reached 700. 
    Runnable 3 reached 700. 
    Runnable 2 reached 700. 
9990 Runnables in the queue. 
    Runnable 9 reached 700. 
    Runnable 4 reached 700. 
    Runnable 6 reached 700. 
    Runnable 0 reached 700. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
    Runnable 1 reached 800. 
9990 Runnables in the queue. 
    Runnable 7 reached 800. 
    Runnable 3 reached 800. 
    Runnable 8 reached 800. 
    Runnable 5 reached 800. 
    Runnable 2 reached 800. 
9990 Runnables in the queue. 
    Runnable 4 reached 800. 
    Runnable 9 reached 800. 
    Runnable 0 reached 800. 
    Runnable 6 reached 800. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
    Runnable 1 reached 900. 
9990 Runnables in the queue. 
    Runnable 7 reached 900. 
    Runnable 8 reached 900. 
    Runnable 5 reached 900. 
    Runnable 9 reached 900. 
    Runnable 3 reached 900. 
    Runnable 2 reached 900. 
9990 Runnables in the queue. 
    Runnable 4 reached 900. 
    Runnable 0 reached 900. 
    Runnable 6 reached 900. 
9990 Runnables in the queue. 
9990 Runnables in the queue. 
    Runnable 1 reached 1000. 
t is null 
[email protected] after execute 
9990 Runnables in the queue. 
9989 Runnables in the queue. 
    Runnable 7 reached 1000. 
t is null 
[email protected] after execute 
    Runnable 8 reached 1000. 
    Runnable 5 reached 1000. 
t is null 
[email protected] after execute 
    Runnable 3 reached 1000. 
t is null 
[email protected] after execute 
t is null 
[email protected] after execute 
9985 Runnables in the queue. 
    Runnable 4 reached 1000. 
    Runnable 2 reached 1000. 
t is null 
[email protected] after execute 
t is null 
[email protected] after execute 
    Runnable 9 reached 1000. 
t is null 
[email protected] after execute 
    Runnable 6 reached 1000. 
t is null 
[email protected] after execute 
9981 Runnables in the queue. 
    Runnable 0 reached 1000. 
t is null 
[email protected] after execute 
9980 Runnables in the queue. 
    Runnable 10 reached 100. 
9980 Runnables in the queue. 
9980 Runnables in the queue. 
    Runnable 11 reached 100. 
    Runnable 12 reached 100. 
    Runnable 14 reached 100. 
    Runnable 16 reached 100. 
9980 Runnables in the queue. 
    Runnable 18 reached 100. 
    Runnable 13 reached 100. 
    Runnable 17 reached 100. 
    Runnable 15 reached 100. 
    Runnable 19 reached 100. 
9980 Runnables in the queue. 
9980 Runnables in the queue. 
    Runnable 10 reached 200. 
9980 Runnables in the queue. 
9980 Runnables in the queue. 
    Runnable 11 reached 200. 
    Runnable 13 reached 200. 
    Runnable 14 reached 200. 
    Runnable 12 reached 200. 
9980 Runnables in the queue. 
    Runnable 16 reached 200. 
    Runnable 18 reached 200. 
    Runnable 15 reached 200. 
Exception in thread "pool-1-thread-3" java.lang.OutOfMemoryError: This is a test! 
    at threadTest.MyRunnable.run(MyRunnable.java:25) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
    at java.lang.Thread.run(Thread.java:680) 
    Runnable 17 reached 200. 
    Runnable 19 reached 200. 
9980 Runnables in the queue. 
9980 Runnables in the queue. 
    Runnable 10 reached 300. 
9980 Runnables in the queue. 
9980 Runnables in the queue. 
    Runnable 11 reached 300. 
    Runnable 12 reached 300. 
    Runnable 13 reached 300. 
9980 Runnables in the queue. 
    Runnable 14 reached 300. 
    Runnable 18 reached 300. 
    Runnable 17 reached 300. 
    Runnable 19 reached 300. 
    Runnable 16 reached 300. 
9980 Runnables in the queue. 
9980 Runnables in the queue. 
    Runnable 10 reached 400. 
9980 Runnables in the queue. 
9980 Runnables in the queue. 
    Runnable 11 reached 400. 
    Runnable 12 reached 400. 
    Runnable 13 reached 400. 
9980 Runnables in the queue. 
    Runnable 18 reached 400. 
    Runnable 14 reached 400. 
    Runnable 17 reached 400. 
9980 Runnables in the queue. 
    Runnable 16 reached 400. 
    Runnable 19 reached 400. 
    Runnable 10 reached 500. 
9980 Runnables in the queue. 
9980 Runnables in the queue. 
9980 Runnables in the queue. 
    Runnable 13 reached 500. 
    Runnable 12 reached 500. 
    Runnable 11 reached 500. 
9980 Runnables in the queue. 
    Runnable 14 reached 500. 
    Runnable 17 reached 500. 
    Runnable 18 reached 500. 
    Runnable 16 reached 500. 
9980 Runnables in the queue. 
    Runnable 19 reached 500. 
    Runnable 10 reached 600. 
9980 Runnables in the queue. 
9980 Runnables in the queue. 
9980 Runnables in the queue. 
    Runnable 13 reached 600. 
9980 Runnables in the queue. 
    Runnable 12 reached 600. 
    Runnable 14 reached 600. 
    Runnable 11 reached 600. 
    Runnable 18 reached 600. 
    Runnable 16 reached 600. 
    Runnable 17 reached 600. 
9980 Runnables in the queue. 
    Runnable 19 reached 600. 
    Runnable 10 reached 700. 
9980 Runnables in the queue. 
9980 Runnables in the queue. 
9980 Runnables in the queue. 
    Runnable 13 reached 700. 
9980 Runnables in the queue. 
    Runnable 11 reached 700. 
    Runnable 14 reached 700. 
    Runnable 18 reached 700. 
    Runnable 16 reached 700. 
    Runnable 12 reached 700. 
9980 Runnables in the queue. 
    Runnable 17 reached 700. 
    Runnable 10 reached 800. 
    Runnable 19 reached 700. 
9980 Runnables in the queue. 
9980 Runnables in the queue. 
9980 Runnables in the queue. 
    Runnable 13 reached 800. 
9980 Runnables in the queue. 
    Runnable 18 reached 800. 
    Runnable 14 reached 800. 
    Runnable 12 reached 800. 
    Runnable 16 reached 800. 
    Runnable 11 reached 800. 
9980 Runnables in the queue. 
    Runnable 17 reached 800. 
    Runnable 10 reached 900. 
9980 Runnables in the queue. 
    Runnable 19 reached 800. 
9980 Runnables in the queue. 
9980 Runnables in the queue. 
    Runnable 13 reached 900. 
    Runnable 18 reached 900. 
9980 Runnables in the queue. 
    Runnable 14 reached 900. 
    Runnable 12 reached 900. 
    Runnable 16 reached 900. 
    Runnable 11 reached 900. 
9980 Runnables in the queue. 
    Runnable 10 reached 1000. 
t is null 
[email protected] after execute 
    Runnable 17 reached 900. 
    Runnable 19 reached 900. 
9979 Runnables in the queue. 
9979 Runnables in the queue. 
9979 Runnables in the queue. 
    Runnable 13 reached 1000. 
    Runnable 18 reached 1000. 
t is null 
[email protected] after execute 
t is null 
[email protected] after execute 
9977 Runnables in the queue. 
    Runnable 14 reached 1000. 
t is null 
[email protected] after execute 
    Runnable 11 reached 1000. 
t is null 
[email protected] after execute 
    Runnable 16 reached 1000. 
t is null 
[email protected] after execute 
    Runnable 12 reached 1000. 
t is null 
[email protected] after execute 
9973 Runnables in the queue. 
    Runnable 20 reached 100. 
    Runnable 17 reached 1000. 
t is null 
[email protected] after execute 
    Runnable 19 reached 1000. 
t is null 
[email protected] after execute 
9971 Runnables in the queue. 
9971 Runnables in the queue. 
9971 Runnables in the queue. 
    Runnable 21 reached 100. 
    Runnable 22 reached 100. 
9971 Runnables in the queue. 
    Runnable 26 reached 100. 
    Runnable 23 reached 100. 
    Runnable 24 reached 100. 
9971 Runnables in the queue. 
    Runnable 25 reached 100. 
    Runnable 28 reached 100. 
    Runnable 20 reached 200. 
    Runnable 27 reached 100. 
9971 Runnables in the queue. 
9971 Runnables in the queue. 
9971 Runnables in the queue. 
9971 Runnables in the queue. 
    Runnable 21 reached 200. 
    Runnable 24 reached 200. 
    Runnable 22 reached 200. 
9971 Runnables in the queue. 
    Runnable 26 reached 200. 
    Runnable 20 reached 300. 
    Runnable 23 reached 200. 
    Runnable 25 reached 200. 
    Runnable 27 reached 200. 
    Runnable 28 reached 200. 
9971 Runnables in the queue. 
9971 Runnables in the queue. 
9971 Runnables in the queue. 
9971 Runnables in the queue. 
    Runnable 24 reached 300. 
9971 Runnables in the queue. 
    Runnable 22 reached 300. 
    Runnable 21 reached 300. 
    Runnable 25 reached 300. 
    Runnable 20 reached 400. 
    Runnable 26 reached 300. 
    Runnable 23 reached 300. 
    Runnable 27 reached 300. 
    Runnable 28 reached 300. 
9971 Runnables in the queue. 
9971 Runnables in the queue. 
9971 Runnables in the queue. 
9971 Runnables in the queue. 
    Runnable 24 reached 400. 
    Runnable 22 reached 400. 
9971 Runnables in the queue. 
    Runnable 21 reached 400. 
    Runnable 26 reached 400. 
    Runnable 20 reached 500. 
    Runnable 23 reached 400. 
    Runnable 25 reached 400. 
    Runnable 27 reached 400. 
9971 Runnables in the queue. 
    Runnable 28 reached 400. 
9971 Runnables in the queue. 
9971 Runnables in the queue. 
9971 Runnables in the queue. 
    Runnable 24 reached 500. 
    Runnable 22 reached 500. 
    Runnable 21 reached 500. 
9971 Runnables in the queue. 
    Runnable 20 reached 600. 
    Runnable 25 reached 500. 
    Runnable 26 reached 500. 
    Runnable 23 reached 500. 
    Runnable 27 reached 500. 
9971 Runnables in the queue. 
    Runnable 28 reached 500. 
9971 Runnables in the queue. 
9971 Runnables in the queue. 
9971 Runnables in the queue. 
    Runnable 25 reached 600. 
    Runnable 24 reached 600. 
    Runnable 22 reached 600. 
    Runnable 20 reached 700. 
9971 Runnables in the queue. 
    Runnable 21 reached 600. 
    Runnable 26 reached 600. 
    Runnable 23 reached 600. 
    Runnable 27 reached 600. 
9971 Runnables in the queue. 
    Runnable 28 reached 600. 
9971 Runnables in the queue. 
9971 Runnables in the queue. 
    Runnable 25 reached 700. 
    Runnable 22 reached 700. 
9971 Runnables in the queue. 
    Runnable 21 reached 700. 
    Runnable 24 reached 700. 
9971 Runnables in the queue. 
    Runnable 23 reached 700. 
    Runnable 20 reached 800. 
    Runnable 27 reached 700. 
    Runnable 26 reached 700. 
    Runnable 28 reached 700. 
9971 Runnables in the queue. 
9971 Runnables in the queue. 
9971 Runnables in the queue. 
    Runnable 25 reached 800. 
    Runnable 22 reached 800. 
9971 Runnables in the queue. 
    Runnable 24 reached 800. 
    Runnable 21 reached 800. 
9971 Runnables in the queue. 
    Runnable 23 reached 800. 
    Runnable 20 reached 900. 
    Runnable 26 reached 800. 
    Runnable 27 reached 800. 
9971 Runnables in the queue. 
    Runnable 28 reached 800. 
9971 Runnables in the queue. 
9971 Runnables in the queue. 
    Runnable 25 reached 900. 
    Runnable 22 reached 900. 
9971 Runnables in the queue. 
    Runnable 24 reached 900. 
    Runnable 21 reached 900. 
    Runnable 20 reached 1000. 
9971 Runnables in the queue. 
t is null 
[email protected] after execute 
    Runnable 23 reached 900. 
    Runnable 27 reached 900. 
9970 Runnables in the queue. 
    Runnable 26 reached 900. 
    Runnable 28 reached 900. 
9970 Runnables in the queue. 
9970 Runnables in the queue. 
    Runnable 22 reached 1000. 
t is null 
[email protected] after execute 
9969 Runnables in the queue. 
    Runnable 24 reached 1000. 
t is null 
[email protected] after execute 
    Runnable 25 reached 1000. 
t is null 
[email protected] after execute 
    Runnable 21 reached 1000. 
t is null 
[email protected] after execute 
9966 Runnables in the queue. 
    Runnable 29 reached 100. 
    Runnable 23 reached 1000. 
t is null 
[email protected] after execute 
9965 Runnables in the queue. 
    Runnable 26 reached 1000. 
t is null 
[email protected] after execute 
    Runnable 27 reached 1000. 
t is null 
[email protected] after execute 
    Runnable 28 reached 1000. 
t is null 
[email protected] after execute 
9962 Runnables in the queue. 
9962 Runnables in the queue. 
    Runnable 30 reached 100. 
    Runnable 32 reached 100. 
9962 Runnables in the queue. 
    Runnable 31 reached 100. 
    Runnable 33 reached 100. 
9962 Runnables in the queue. 
    Runnable 34 reached 100. 
    Runnable 29 reached 200. 
    Runnable 35 reached 100. 
9962 Runnables in the queue. 
    Runnable 37 reached 100. 
    Runnable 36 reached 100. 
9962 Runnables in the queue. 
9962 Runnables in the queue. 
    Runnable 30 reached 200. 
    Runnable 32 reached 200. 
9962 Runnables in the queue. 
    Runnable 31 reached 200. 
9962 Runnables in the queue. 
    Runnable 33 reached 200. 
    Runnable 29 reached 300. 
    Runnable 34 reached 200. 
9962 Runnables in the queue. 
    Runnable 35 reached 200. 
    Runnable 37 reached 200. 
    Runnable 36 reached 200. 
9962 Runnables in the queue. 
9962 Runnables in the queue. 
    Runnable 30 reached 300. 
    Runnable 32 reached 300. 
9962 Runnables in the queue. 
    Runnable 31 reached 300. 
9962 Runnables in the queue. 
    Runnable 33 reached 300. 
    Runnable 29 reached 400. 
9962 Runnables in the queue. 
    Runnable 34 reached 300. 
    Runnable 35 reached 300. 
    Runnable 36 reached 300. 
    Runnable 37 reached 300. 
9962 Runnables in the queue. 
9962 Runnables in the queue. 
    Runnable 32 reached 400. 
    Runnable 30 reached 400. 
9962 Runnables in the queue. 
9962 Runnables in the queue. 
    Runnable 31 reached 400. 
    Runnable 33 reached 400. 
9962 Runnables in the queue. 
    Runnable 29 reached 500. 
    Runnable 34 reached 400. 
    Runnable 35 reached 400. 
    Runnable 37 reached 400. 
9962 Runnables in the queue. 
    Runnable 36 reached 400. 
9962 Runnables in the queue. 
    Runnable 30 reached 500. 
    Runnable 32 reached 500. 
9962 Runnables in the queue. 
9962 Runnables in the queue. 
    Runnable 33 reached 500. 
    Runnable 31 reached 500. 
    Runnable 34 reached 500. 
    Runnable 29 reached 600. 
9962 Runnables in the queue. 
    Runnable 37 reached 500. 
    Runnable 35 reached 500. 
9962 Runnables in the queue. 
    Runnable 36 reached 500. 
9962 Runnables in the queue. 
    Runnable 30 reached 600. 
    Runnable 32 reached 600. 
9962 Runnables in the queue. 
9962 Runnables in the queue. 
    Runnable 33 reached 600. 
    Runnable 31 reached 600. 
    Runnable 29 reached 700. 
9962 Runnables in the queue. 
    Runnable 34 reached 600. 
9962 Runnables in the queue. 
    Runnable 37 reached 600. 
    Runnable 35 reached 600. 
    Runnable 36 reached 600. 
    Runnable 30 reached 700. 
9962 Runnables in the queue. 
    Runnable 32 reached 700. 
9962 Runnables in the queue. 
9962 Runnables in the queue. 
    Runnable 33 reached 700. 
    Runnable 31 reached 700. 
9962 Runnables in the queue. 
    Runnable 34 reached 700. 
    Runnable 29 reached 800. 
    Runnable 37 reached 700. 
    Runnable 35 reached 700. 
9962 Runnables in the queue. 
    Runnable 30 reached 800. 
    Runnable 36 reached 700. 
9962 Runnables in the queue. 
    Runnable 32 reached 800. 
9962 Runnables in the queue. 
9962 Runnables in the queue. 
    Runnable 33 reached 800. 
    Runnable 31 reached 800. 
    Runnable 29 reached 900. 
    Runnable 34 reached 800. 
9962 Runnables in the queue. 
    Runnable 35 reached 800. 
    Runnable 37 reached 800. 
9962 Runnables in the queue. 
    Runnable 30 reached 900. 
9962 Runnables in the queue. 
    Runnable 36 reached 800. 
    Runnable 32 reached 900. 
9962 Runnables in the queue. 
9962 Runnables in the queue. 
    Runnable 33 reached 900. 
    Runnable 34 reached 900. 
    Runnable 29 reached 1000. 
    Runnable 31 reached 900. 
9962 Runnables in the queue. 
t is null 
[email protected] after execute 
    Runnable 35 reached 900. 
    Runnable 37 reached 900. 
9961 Runnables in the queue. 
    Runnable 30 reached 1000. 
t is null 
[email protected] after execute 
    Runnable 36 reached 900. 
9960 Runnables in the queue. 
    Runnable 32 reached 1000. 
t is null 
[email protected] after execute 
9959 Runnables in the queue. 
9959 Runnables in the queue. 
    Runnable 33 reached 1000. 
t is null 
[email protected] after execute 
    Runnable 38 reached 100. 
    Runnable 34 reached 1000. 
9958 Runnables in the queue. 
t is null 
[email protected] after execute 
    Runnable 31 reached 1000. 
t is null 
[email protected] after execute 
    Runnable 37 reached 1000. 
t is null 
[email protected] after execute 
    Runnable 35 reached 1000. 
t is null 
[email protected] after execute 
9954 Runnables in the queue. 
    Runnable 39 reached 100. 
    Runnable 36 reached 1000. 
t is null 
[email protected] after execute 
9953 Runnables in the queue. 
    Runnable 40 reached 100. 
9953 Runnables in the queue. 
9953 Runnables in the queue. 
    Runnable 42 reached 100. 
    Runnable 41 reached 100. 
9953 Runnables in the queue. 
    Runnable 38 reached 200. 
    Runnable 43 reached 100. 
    Runnable 44 reached 100. 
9953 Runnables in the queue. 
    Runnable 45 reached 100. 
    Runnable 46 reached 100. 
9953 Runnables in the queue. 
    Runnable 39 reached 200. 
    Runnable 40 reached 200. 
9953 Runnables in the queue. 
9953 Runnables in the queue. 
    Runnable 42 reached 200. 
    Runnable 41 reached 200. 
9953 Runnables in the queue. 
    Runnable 38 reached 300. 
    Runnable 44 reached 200. 
    Runnable 43 reached 200. 
9953 Runnables in the queue. 
    Runnable 45 reached 200. 
    Runnable 46 reached 200. 
9953 Runnables in the queue. 
    Runnable 39 reached 300. 
    Runnable 40 reached 300. 
9953 Runnables in the queue. 
9953 Runnables in the queue. 
    Runnable 41 reached 300. 
    Runnable 42 reached 300. 
9953 Runnables in the queue. 
    Runnable 38 reached 400. 
    Runnable 44 reached 300. 
    Runnable 43 reached 300. 
    Runnable 45 reached 300. 
9953 Runnables in the queue. 
    Runnable 46 reached 300. 
9953 Runnables in the queue. 
    Runnable 40 reached 400. 
9953 Runnables in the queue. 
    Runnable 39 reached 400. 
9953 Runnables in the queue. 
    Runnable 41 reached 400. 
9953 Runnables in the queue. 
    Runnable 42 reached 400. 
    Runnable 38 reached 500. 
    Runnable 44 reached 400. 
    Runnable 43 reached 400. 
    Runnable 45 reached 400. 
9953 Runnables in the queue. 
    Runnable 46 reached 400. 
9953 Runnables in the queue. 
    Runnable 40 reached 500. 
9953 Runnables in the queue. 
    Runnable 39 reached 500. 
    Runnable 41 reached 500. 
9953 Runnables in the queue. 
    Runnable 42 reached 500. 
9953 Runnables in the queue. 
    Runnable 43 reached 500. 
    Runnable 38 reached 600. 
9953 Runnables in the queue. 
    Runnable 45 reached 500. 
    Runnable 44 reached 500. 
    Runnable 46 reached 500. 
9953 Runnables in the queue. 
    Runnable 40 reached 600. 
    Runnable 39 reached 600. 
9953 Runnables in the queue. 
    Runnable 41 reached 600. 
9953 Runnables in the queue. 
    Runnable 42 reached 600. 
9953 Runnables in the queue. 
    Runnable 43 reached 600. 
    Runnable 44 reached 600. 
    Runnable 38 reached 700. 
9953 Runnables in the queue. 
    Runnable 45 reached 600. 
9953 Runnables in the queue. 
    Runnable 40 reached 700. 
    Runnable 46 reached 600. 
9953 Runnables in the queue. 
    Runnable 39 reached 700. 
    Runnable 41 reached 700. 
9953 Runnables in the queue. 
    Runnable 42 reached 700. 
9953 Runnables in the queue. 
    Runnable 43 reached 700. 
    Runnable 38 reached 800. 
9953 Runnables in the queue. 
    Runnable 44 reached 700. 
    Runnable 45 reached 700. 
9953 Runnables in the queue. 
    Runnable 46 reached 700. 
    Runnable 40 reached 800. 
    Runnable 39 reached 800. 
9953 Runnables in the queue. 
9953 Runnables in the queue. 
    Runnable 41 reached 800. 
    Runnable 42 reached 800. 
9953 Runnables in the queue. 
    Runnable 43 reached 800. 
    Runnable 44 reached 800. 
    Runnable 38 reached 900. 
9953 Runnables in the queue. 
    Runnable 45 reached 800. 
9953 Runnables in the queue. 
    Runnable 46 reached 800. 
    Runnable 40 reached 900. 
9953 Runnables in the queue. 
    Runnable 39 reached 900. 

UPDATE: 這是我從官方文檔了在http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html 這證實觀察到的行爲

Note: When actions are enclosed in tasks (such as FutureTask) either explicitly or via methods such as submit, these task objects catch and maintain computational exceptions, and so they do not cause abrupt termination, and the internal exceptions are not passed to this method. If you would like to trap both kinds of failures in this method, you can further probe for such cases, as in this sample subclass that prints either the direct cause or the underlying exception if a task has been aborted:

+1

我其實讀過這個,但在這種情況下,我並沒有把它包裝在一個'FutureTask'中。此外,OutOfMemoryError不是計算錯誤,是嗎? 「計算」錯誤更像NumberFormatException或NullPointerException,如我期望的示例代碼那樣具有諷刺意味。事實上,如果你閱讀了ThreadPoolExecutor.runWorker()的源代碼(在第1098行左右),那麼對afterExecute()的調用就是在finally中,因此應該在每次迭代之後調用** 。 – CodeChimp 2014-09-08 11:34:13