目次
スレッド プールの基本原理
スレッド プール拒否ポリシー
AbortPolicy
DiscardOldestPolicy タスクの追加が拒否された場合、最初にキューに追加されたタスクが破棄され、新しいタスクが追加されます。
実行結果:
自定义拒绝策略
小结
ホームページ Java &#&チュートリアル Java ThreadPoolExecutor の拒否ポリシーを実装するにはどうすればよいですか?

Java ThreadPoolExecutor の拒否ポリシーを実装するにはどうすればよいですか?

May 08, 2023 pm 03:34 PM
java threadpoolexecutor

    スレッド プールの基本原理

    スレッド プールの原理は次のとおりです。

    Java ThreadPoolExecutor の拒否ポリシーを実装するにはどうすればよいですか?

    手順:

    • 現在実行中のスレッドの数が corePoolSize 未満の場合は、タスクを実行するための新しいスレッドを作成します。

    • 実行中のスレッドが corePoolSize 以上の場合、タスクはキューに追加されます。

    • タスク キューがいっぱいになると、タスクを処理するために非コアプールに新しいスレッドが作成されます。

    • 新しいスレッドを作成すると、現在実行中のスレッドが MaximumPoolSize を超え、タスクが拒否され、RejectedExecutionHandler.rejectedExecution() メソッドが呼び出されます。

    スレッド プール拒否ポリシー

    スレッド プールには、CallerRunsPolicy、AbortPolicy、DiscardPolicy、DiscardOldestPolicy

    AbortPolicy

    # の 4 つの拒否ポリシーが用意されています。 ##ThreadPoolExecutor のデフォルトの拒否戦略は、AbortPolicy が直接例外をスローすることです。具体的な実装は次のとおりです

    public static class AbortPolicy implements RejectedExecutionHandler {
        public AbortPolicy() { }
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " + r.toString() +
                                                 " rejected from " +
                                                 e.toString());
        }
    }
    ログイン後にコピー

    説明: この戦略は非常に単純かつ粗雑です。直接 RejectedExecutionException 例外をスローし、実行されませんその後のタスク。

    説明例:

    public class ThreadPoolTest
    {
        public static void main(String[] args)
        {
            ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                    2,
                    5,
                    10,
                    TimeUnit.MICROSECONDS,
                    new LinkedBlockingDeque<>(1),
                    new ThreadPoolExecutor.AbortPolicy());
            
            //异步执行
            for(int i=0; i<10;i++)
            {
              System.out.println("添加第"+i+"个任务");
              threadPoolExecutor.execute(new TestThread("线程"+i));
            }        
        }
    }
    
    public class TestThread implements Runnable
    {
        private String name;
        public TestThread(String name){
            this.name=name;
        }
        
        @Override
        public void run()
        {
            try
            {
                Thread.sleep(1000);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            System.out.println("thread name:"+Thread.currentThread().getName()+",执行:"+name);
        }
    }
    ログイン後にコピー

    実行結果:

    スレッド「メイン」の例外 java.util.concurrent.RejectedExecutionException: タスク com.skywares.fw.juc .thread.TestThread@55f96302 が java.util.concurrent.ThreadPoolExecutor@3d4eac69[実行中、プール サイズ = 5、アクティブ スレッド = 5、キューに入れられたタスク = 1、完了したタスク = 0]

    から拒否されました。 ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)
    で java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
    で java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java: 1369)
    com.skywares.fw.juc.thread.ThreadPoolTest.main(ThreadPoolTest.java:26)
    スレッド名:pool-1-thread-5、実行: スレッド 5
    スレッド名:プール-1-スレッド-2、実行: スレッド 1
    スレッド名: プール-1-スレッド-4、実行: スレッド 4
    スレッド名: プール-1-スレッド-3、実行: スレッド 3
    スレッド名: pool-1-thread-1、実行: スレッド 0
    スレッド名: pool-1-thread-5、実行: スレッド 2

    実行結果から、 AbortPolicy 戦略を使用すると、タスクが 7 番目のタスクに実行されるときにエラーが直接報告され、後続のビジネス ロジックは実行されません。

    CallerRunsPolicy

    タスクが拒否された後、CallerRunsPolicy は、実行関数を呼び出す上位スレッドを使用して、拒否されたタスクを実行します。

    関連例

    public class ThreadPoolTest
    {
        public static void main(String[] args)
        {
            ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                    2,
                    5,
                    10,
                    TimeUnit.MICROSECONDS,
                    new LinkedBlockingDeque<>(1),
                    new ThreadPoolExecutor.CallerRunsPolicy());
            
            //异步执行
            for(int i=0; i<10;i++)
            {
              System.out.println("添加第"+i+"个任务");
              threadPoolExecutor.execute(new TestThread("线程"+i));
            }
        }
    }
    ログイン後にコピー

    実行結果:

    0 番目のタスクを追加

    1 番目のタスクを追加
    2 番目のタスクを追加
    3 番目のタスク
    4 番目のタスクを追加
    5 番目のタスクを追加
    6 番目のタスクを追加
    スレッド名:main、実行:スレッド 6
    スレッド名:pool-1-thread-3、実行: スレッド 3
    スレッド名: pool-1-thread-1、実行: スレッド 0
    スレッド名: pool-1-thread-4、実行: スレッド 4
    スレッド名:pool-1-thread -2、実行: スレッド 1
    スレッド名: pool-1-thread-5、実行: スレッド 5
    7 番目のタスクを追加
    8 番目のタスクを追加
    スレッド名:メイン、実行:スレッド8
    スレッド名:pool-1-thread-1,execution:thread 7
    thread name:pool-1-thread-3,execution:thread 2
    9 番目のタスクを追加
    スレッド名: pool-1-thread-1、実行: スレッド 9

    実行結果から、7 番目のタスクが実行されると、スレッド プールの拒否ポリシーにより、このタスクはスレッド プールがアイドル状態のとき、メイン スレッドやその他のタスクは実行され続けます。

    したがって、この戦略はメインスレッドをブロックする可能性があります。

    DiscardPolicy

    この拒否ポリシーは比較的単純です。スレッド プールによって拒否されたタスクは、例外をスローしたり、

    Example

    を実行したりせずに、直接破棄されます。上記のコードを変更し、拒否ポリシーを DiscardPolicy

     ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                    2,
                    5,
                    10,
                    TimeUnit.MICROSECONDS,
                    new LinkedBlockingDeque<>(1),
                    new ThreadPoolExecutor.CallerRunsPolicy());
    ログイン後にコピー

    Execution result

    invoke dealStock success
    goodsId:mobilephone

    thread name:pool-1- thread- に変更します。 1、実行: スレッド 0
    スレッド名: プール-1-スレッド-4、実行: スレッド 4
    スレッド名: プール-1-スレッド-5、実行: スレッド 5
    スレッド名: プール- 1-スレッド-3、実行: スレッド 3
    スレッド名: プール-1-スレッド-2、実行: スレッド 1
    スレッド名: プール-1-スレッド-1、実行: スレッド 2

    実行結果から判断すると、6 つのタスクのみが実行され、他のタスクは放棄されました。

    DiscardOldestPolicy

    DiscardOldestPolicy タスクの追加が拒否された場合、最初にキューに追加されたタスクが破棄され、新しいタスクが追加されます。

    記述例

     ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                    1,
                    2,
                    10,
                    TimeUnit.MICROSECONDS,
                    new LinkedBlockingDeque<>(2),
                    new ThreadPoolExecutor.CallerRunsPolicy());
    ログイン後にコピー

    実行結果:

    0番目のタスクを追加
    1番目のタスクを追加

    2番目のタスクを追加
    3 番目のタスク
    4 番目のタスクを追加
    5 番目のタスクを追加
    dealStock の成功を呼び出す
    goodsId: 携帯電話
    スレッド名:pool-1-thread-2、実行: Thread 3
    スレッド名:pool-1-thread-1、実行:スレッド 0
    スレッド名:pool-1-thread-1、実行:スレッド 2
    スレッド名:pool-1-thread- 2. 実行:スレッド1

    自定义拒绝策略

    当线程池提供的拒绝策略无法满足要求时,我们可以采用自定义的拒绝策略,只需要实现RejectedExecutionHandler接口即可

    public class CustRejectedExecutionHandler implements RejectedExecutionHandler
    {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor)
        {
            new Thread(r,"线程:"+new Random().nextInt(10)).start();
        }
    }
    
      ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                    1,
                    2,
                    10,
                    TimeUnit.MICROSECONDS,
                    new LinkedBlockingDeque<>(2),
                    new CustRejectedExecutionHandler());
    ログイン後にコピー

    执行结果:

    thread name:客户线程:6,执行:线程5
    thread name:pool-1-thread-1,执行:线程0
    thread name:客户线程:8,执行:线程4
    thread name:pool-1-thread-2,执行:线程3
    thread name:pool-1-thread-1,执行:线程1
    thread name:pool-1-thread-2,执行:线程2

    从执行的结果来看,被拒绝的任务都在客户的新线程中执行。

    小结

    • AbortPolicy:直接抛出异常,后续的任务不会执行

    • CallerRunsPolicy:子任务执行的时间过长,可能会阻塞主线程。

    • DiscardPolicy:不抛异常,任务直接丢弃

    • DiscardOldestPolicy;丢弃最先加入队列的任务

    以上がJava ThreadPoolExecutor の拒否ポリシーを実装するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    このウェブサイトの声明
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

    ホットAIツール

    Undresser.AI Undress

    Undresser.AI Undress

    リアルなヌード写真を作成する AI 搭載アプリ

    AI Clothes Remover

    AI Clothes Remover

    写真から衣服を削除するオンライン AI ツール。

    Undress AI Tool

    Undress AI Tool

    脱衣画像を無料で

    Clothoff.io

    Clothoff.io

    AI衣類リムーバー

    AI Hentai Generator

    AI Hentai Generator

    AIヘンタイを無料で生成します。

    ホットツール

    メモ帳++7.3.1

    メモ帳++7.3.1

    使いやすく無料のコードエディター

    SublimeText3 中国語版

    SublimeText3 中国語版

    中国語版、とても使いやすい

    ゼンドスタジオ 13.0.1

    ゼンドスタジオ 13.0.1

    強力な PHP 統合開発環境

    ドリームウィーバー CS6

    ドリームウィーバー CS6

    ビジュアル Web 開発ツール

    SublimeText3 Mac版

    SublimeText3 Mac版

    神レベルのコード編集ソフト(SublimeText3)

    Javaの平方根 Javaの平方根 Aug 30, 2024 pm 04:26 PM

    Java の平方根のガイド。ここでは、Java で平方根がどのように機能するかを、例とそのコード実装をそれぞれ示して説明します。

    Javaの完全数 Javaの完全数 Aug 30, 2024 pm 04:28 PM

    Java における完全数のガイド。ここでは、定義、Java で完全数を確認する方法、コード実装の例について説明します。

    Java の乱数ジェネレーター Java の乱数ジェネレーター Aug 30, 2024 pm 04:27 PM

    Java の乱数ジェネレーターのガイド。ここでは、Java の関数について例を挙げて説明し、2 つの異なるジェネレーターについて例を挙げて説明します。

    ジャワのウェカ ジャワのウェカ Aug 30, 2024 pm 04:28 PM

    Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

    Javaのスミス番号 Javaのスミス番号 Aug 30, 2024 pm 04:28 PM

    Java のスミス番号のガイド。ここでは定義、Java でスミス番号を確認する方法について説明します。コード実装の例。

    Java Springのインタビューの質問 Java Springのインタビューの質問 Aug 30, 2024 pm 04:29 PM

    この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

    Java 8 Stream Foreachから休憩または戻ってきますか? Java 8 Stream Foreachから休憩または戻ってきますか? Feb 07, 2025 pm 12:09 PM

    Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです

    Java での日付までのタイムスタンプ Java での日付までのタイムスタンプ Aug 30, 2024 pm 04:28 PM

    Java での日付までのタイムスタンプに関するガイド。ここでは、Java でタイムスタンプを日付に変換する方法とその概要について、例とともに説明します。

    See all articles