ThreadPoolExecutor忽略错误(OutOfMemoryError)

时间:2014-09-05 14:16:32

标签: java java-7 java-6 threadpoolexecutor

我们正在撰写一个使用ThreadPoolExecutor自定义扩展程序来处理一堆Runnable的应用。在开发应用程序时,我们遇到了OutOfMemoryError类中发生的Runnable个问题。但是,afterExecute()不是像我们期望的那样调用我们的ThreadPoolExecutor而是继续卡车运输。

我已将代码削减为一个小型,可重复的应用程序。

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中创建10k MyThreadPoolExectuor个,在计数器增加时打印出一些状态消息。第16个runnable(数字15,从0开始计数)将在第200个增量上抛出OutOfMemoryErrorMyThreadPoolExecutor的{​​{1}}如果收到afterExecute(),则会打印一条消息。当我在Java 6和Java 7下运行它时,它从不打印此消息。

我们如何让所有Throwable的应用程序保释?我们真的想在那时终止事情。

更新/编辑:

我正在更新这个,因为我要问的是什么似乎有些混乱。 我知道错误被打印出来。问题不在于ThreadPoolExecutor没有打印Throwable,问题是,如标题和我最后要问的问题所述,OutOfMemoryError没有调用afterExecute()。由于ErrorOutOfMemoryError的子类,这意味着一旦发生,我就 NO WAY 来停止代码。

再次,请阅读代码尝试执行的操作。它肯定试图“处理”错误。事实上,它试图通过调用Error来阻止ThreadPoolExecutor。但是,由于正在生成的shutdownNow()被某种方式抑制,所以这段代码没有被执行。因此,该应用程序只是一直在努力,忽略了它在整个地方喷出OOME的事实。

同样,问题:

  

如何检测Runnable已收到错误(OutOfMemoryError或   其他)并终止ThreadPoolExecutor所以应用程序将简单   停在它的轨道上?

2 个答案:

答案 0 :(得分:0)

让我简单解释一下代码,如果查看runWorker()实现,发现错误仍然在afterExecute()中发送。因此,如果使用afterExecute钩子,则无法跳过错误。请参阅https://stackoverflow.com/a/50480190/5620851

InitiatingFlow

答案 1 :(得分:-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
threadTest.MyRunnable@7d29f3b5 after execute
9990 Runnables in the queue.
9989 Runnables in the queue.
    Runnable 7 reached 1000.
t is null
threadTest.MyRunnable@4d3f3045 after execute
    Runnable 8 reached 1000.
    Runnable 5 reached 1000.
t is null
threadTest.MyRunnable@6f7a29a1 after execute
    Runnable 3 reached 1000.
t is null
threadTest.MyRunnable@3d434234 after execute
t is null
threadTest.MyRunnable@aaf8358 after execute
9985 Runnables in the queue.
    Runnable 4 reached 1000.
    Runnable 2 reached 1000.
t is null
threadTest.MyRunnable@8d80be3 after execute
t is null
threadTest.MyRunnable@1ff4689e after execute
    Runnable 9 reached 1000.
t is null
threadTest.MyRunnable@67006d75 after execute
    Runnable 6 reached 1000.
t is null
threadTest.MyRunnable@4d125127 after execute
9981 Runnables in the queue.
    Runnable 0 reached 1000.
t is null
threadTest.MyRunnable@33db4f6f 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
threadTest.MyRunnable@10b61fd1 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
threadTest.MyRunnable@24e2dae9 after execute
t is null
threadTest.MyRunnable@299209ea after execute
9977 Runnables in the queue.
    Runnable 14 reached 1000.
t is null
threadTest.MyRunnable@32c8f6f8 after execute
    Runnable 11 reached 1000.
t is null
threadTest.MyRunnable@27ce2dd4 after execute
    Runnable 16 reached 1000.
t is null
threadTest.MyRunnable@5122cdb6 after execute
    Runnable 12 reached 1000.
t is null
threadTest.MyRunnable@43ef9157 after execute
9973 Runnables in the queue.
    Runnable 20 reached 100.
    Runnable 17 reached 1000.
t is null
threadTest.MyRunnable@252f0999 after execute
    Runnable 19 reached 1000.
t is null
threadTest.MyRunnable@331f2ee1 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
threadTest.MyRunnable@443ecfff 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
threadTest.MyRunnable@77c99159 after execute
9969 Runnables in the queue.
    Runnable 24 reached 1000.
t is null
threadTest.MyRunnable@5265a77f after execute
    Runnable 25 reached 1000.
t is null
threadTest.MyRunnable@fd7ad1c after execute
    Runnable 21 reached 1000.
t is null
threadTest.MyRunnable@18a61164 after execute
9966 Runnables in the queue.
    Runnable 29 reached 100.
    Runnable 23 reached 1000.
t is null
threadTest.MyRunnable@3ebfc8e0 after execute
9965 Runnables in the queue.
    Runnable 26 reached 1000.
t is null
threadTest.MyRunnable@211d0a4f after execute
    Runnable 27 reached 1000.
t is null
threadTest.MyRunnable@798fd984 after execute
    Runnable 28 reached 1000.
t is null
threadTest.MyRunnable@5311a775 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
threadTest.MyRunnable@2c091cee after execute
    Runnable 35 reached 900.
    Runnable 37 reached 900.
9961 Runnables in the queue.
    Runnable 30 reached 1000.
t is null
threadTest.MyRunnable@a4a63d8 after execute
    Runnable 36 reached 900.
9960 Runnables in the queue.
    Runnable 32 reached 1000.
t is null
threadTest.MyRunnable@19e0ff2f after execute
9959 Runnables in the queue.
9959 Runnables in the queue.
    Runnable 33 reached 1000.
t is null
threadTest.MyRunnable@29173ef after execute
    Runnable 38 reached 100.
    Runnable 34 reached 1000.
9958 Runnables in the queue.
t is null
threadTest.MyRunnable@1b52513a after execute
    Runnable 31 reached 1000.
t is null
threadTest.MyRunnable@3952c4d9 after execute
    Runnable 37 reached 1000.
t is null
threadTest.MyRunnable@68f99ff5 after execute
    Runnable 35 reached 1000.
t is null
threadTest.MyRunnable@5c74c3aa after execute
9954 Runnables in the queue.
    Runnable 39 reached 100.
    Runnable 36 reached 1000.
t is null
threadTest.MyRunnable@75d9fd51 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.

更新: 这是我从http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html的官方文档中得到的 这证实了观察到的行为

  

注意:当任务(例如FutureTask)中包含操作时   显式或通过诸如submit之类的方法,这些任务对象捕获和   保持计算异常,所以它们不会导致突然   终止,内部异常不会传递给它   方法即可。如果您想在此捕获两种类型的故障   方法,您可以进一步探测此类情况,如本示例所示   打印直接原因或基础的子类   如果任务已中止,则出现异常: