2

我刚刚阅读了这篇文章Runnable,并认为如果抛出异常并退出,线程池可能会耗尽工作线程。我做了一个小代码并检查了,但池大小没有变化。

public class ThreadPoolTest {

public static void main(String[] args) throws InterruptedException {
    ThreadPoolExecutor tp = new ThreadPoolExecutor(1, 1, 5, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1));
    Thread.sleep(1000);
    System.out.println(tp.getPoolSize());
    tp.execute(new Runnable(){

        @Override
        public void run() {
            System.out.println("Executing & Throwing");
            throw new NullPointerException();
        }

    });
    Thread.sleep(1000);
    System.out.println(tp.getPoolSize());
    tp.execute(new Runnable(){

        @Override
        public void run() {
            System.out.println("Executing & Throwing");
            throw new NullPointerException();
        }

    });
    Thread.sleep(1000);
    System.out.println(tp.getPoolSize());
    tp.shutdown();
}

}

我得到的输出是

0
Exception in thread "pool-1-thread-1" java.lang.NullPointerException
    at threads.ThreadPoolTest$1.run(ThreadPoolTest.java:18)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Executing & Throwing
1
Exception in thread "pool-1-thread-2" java.lang.NullPointerException
    at threads.ThreadPoolTest$2.run(ThreadPoolTest.java:29)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Executing & Throwing
1

这是在 Java 7 上。如文章中所述,是否有任何易受攻击的 java Threadpool 实现?

4

2 回答 2

1

阅读这篇文章,要点是写得不好的线程池可能会遇到这个问题。事实上,任何创建线程并且不/不能处理来自该线程的未捕获异常的应用程序。

我希望任何有信誉的线程池来源都能以某种方式处理这种情况。信誉良好,我将包括 Oracle 采购的解决方案。我怀疑如果有人手工编写线程池并且他们缺乏经验,那么他们会编写一个不太健壮的解决方案。

于 2013-03-15T09:57:24.000 回答
1

文章指出:

标准线程池允许未捕获的任务异常终止池线程

就是这样。稍加修改的代码版本显示,当前一个线程因异常而死亡时,ThreadPool 将创建一个新线程。

作为旁注,您通常会使用该submit方法,并尝试get在返回的 Future 上查看是否引发了异常。

输出:

0
Creating new thread
Executing & Throwing
Creating new thread
Exception in thread "Thread-0" java.lang.NullPointerException
    at javaapplication4.Test2$2.run(Test2.java:47)
    ....
1
Executing & Throwing
Creating new thread
Exception in thread "Thread-1" java.lang.NullPointerException
    at javaapplication4.Test2$3.run(Test2.java:56)
    ....
1

代码:

public static void main(String[] args) throws InterruptedException {
    ThreadPoolExecutor tp = new ThreadPoolExecutor(1, 1, 5, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1), new ThreadFactory() {

        @Override
        public Thread newThread(Runnable r) {
            System.out.println("Creating new thread");
            return new Thread(r);
        }
    });
    Thread.sleep(1000);
    System.out.println(tp.getPoolSize());
    tp.execute(new Runnable() {
        @Override
        public void run() {
            System.out.println("Executing & Throwing");
            throw new NullPointerException();
        }
    });
    Thread.sleep(100);
    System.out.println(tp.getPoolSize());
    tp.execute(new Runnable() {
        @Override
        public void run() {
            System.out.println("Executing & Throwing");
            throw new NullPointerException();
        }
    });
    Thread.sleep(100);
    System.out.println(tp.getPoolSize());
    tp.shutdown();
}
于 2013-03-15T10:07:03.160 回答