2014-09-05 4 views
1

Мы пишем приложение, которое использует пользовательское расширение ThreadPoolExecutor для обработки связки Runnable s. При разработке приложения мы столкнулись с OutOfMemoryError s, которые произошли в наших классах Runnable. Но вместо того, чтобы называть наш 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); 
       } 
      } 
     } 
    } 
} 

Это супер-простой пример, который будет создавать 10k из MyRunnable с в MyThreadPoolExectuor, распечатывая некоторые сообщения о статусе как счетчики i ncrease. 16-й ход (число 15, отсчет от 0) будет вызывать OutOfMemoryError на 200-м приращении. MyThreadPoolExecutorafterExecute() напечатает сообщение, если оно получит Throwable. Когда я запускаю его под Java 6 и Java 7, он никогда не печатает это сообщение.

Как мы можем сделать поручительство на все Throwable? Мы действительно хотим просто прекратить дело в этот момент.

Update/Edit:

Я обновляю это как кажется, есть некоторая путаница относительно того, что я прошу. Я знаю, что ошибка печатается. Проблема не в том, что ThreadPoolExecutor не печатает OutOfMemoryError, проблема в том, что указано в заголовке и в вопросе, который я задаю в конце, что afterExecute() не вызывается для Error s. Так как OutOfMemoryError является подклассом Error, это означает, что когда происходит, у меня есть NO WAY, чтобы остановить код.

Снова прочитайте, что делает код. Это, безусловно, пытается «обработать» ошибку. Фактически он пытается остановить ThreadPoolExecutor, вызвав на нем shutdownNow(). Но, поскольку генерируемое 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

+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

+0

Работает для меня .. Я вижу ошибку. –

ответ

-1

Я запустить свой код и вот мои выводы. Ошибка в одной задаче не является блокирующей для других. В нижнем выпуске ошибка возникает после 16-й задачи, но программа не завершается, и другие задачи успешно выполняются. Только после выполнения 1000-й задачи вызывается метод afterExecute. Возможно, вы ожидаете, что afterExecute будет вызываться после каждой задачи. Но это не тот случай. Также похоже, что метод afterExecute не получает возможность запускаться на уровне задачи, а скорее на уровне threadpool.

Я изменил 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 
threa[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