java 线程抛出 RuntimeException - 对线程池的影响

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15429227/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 19:33:15  来源:igfitidea点击:

Threads throwing RuntimeException - Impact on Threadpool

javathreadpool

提问by R Kaja Mohideen

I just read this articleand thought that threadpool may run out of worker threads if the Runnable's throw exception and exit. I did a small code and checked, but the poolsize didn't vary.

我刚刚读了这篇文章,认为如果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();
}

}

}

Output I got was

我得到的输出是

0
Exception in thread "pool-1-thread-1" java.lang.NullPointerException
    at threads.ThreadPoolTest.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.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

This is on Java 7. Is there any java Threadpool implementation which is vulnerable as stated in the article?

这是在 Java 7 上。是否有文章中所述的易受攻击的 Java 线程池实现?

采纳答案by Brian Agnew

Reading the article, the gist is that a poorly written thread pool can suffer from this problem. In fact, any application that creates a thread and doesn't/can't handle an uncaught exception from that thread.

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

I'd expect any reputable source of a thread pool to handle this scenario in some fashion. By reputable, I would include the Oracle-sourced solutions. I suspect if someone was hand-coding a thread pool and they lacked experience then they'd write a less-robust solution.

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

回答by assylias

The article states:

文章指出:

The standard thread pools allow an uncaught task exception to terminate the pool thread

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

which is the case. A slightly amended version of your code shows that the ThreadPool will create a new thread when the previous has died due to an exception.

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

As a side comment, you would in general use the submitmethod, and try to geton the returned Future to see if an exception has be thrown.

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

Output:

输出:

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

Code:

代码:

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();
}