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

記事には次のように記載されています。

標準のスレッド プールでは、キャッチされていないタスク例外がプール スレッドを終了させることができます。

これは事実です。コードのわずかに修正されたバージョンは、例外が原因で前のスレッドが終了したときに ThreadPool が新しいスレッドを作成することを示しています。

余談ですが、通常はこのメソッドを使用し、返された Future をsubmit試して、例外がスローされたかどうかを確認します。get

出力:

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 に答える
1

記事を読むと、要点は、不適切に作成されたスレッド プールがこの問題に悩まされる可能性があるということです。実際、スレッドを作成し、そのスレッドからのキャッチされていない例外を処理しない/処理できないアプリケーション。

スレッドプールの評判の良いソースがこのシナリオを何らかの方法で処理することを期待しています。評判が良いということで、オラクルが提供するソリューションを含めます。誰かがスレッドプールを手作業でコーディングしていて、経験が不足している場合、堅牢性の低いソリューションを作成するのではないかと思います。

于 2013-03-15T09:57:24.000 に答える