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()); } }
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]実行結果から、 AbortPolicy 戦略を使用すると、タスクが 7 番目のタスクに実行されるときにエラーが直接報告され、後続のビジネス ロジックは実行されません。 CallerRunsPolicyタスクが拒否された後、CallerRunsPolicy は、実行関数を呼び出す上位スレッドを使用して、拒否されたタスクを実行します。 関連例から拒否されました。 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
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 番目のタスクを追加実行結果から、7 番目のタスクが実行されると、スレッド プールの拒否ポリシーにより、このタスクはスレッド プールがアイドル状態のとき、メイン スレッドやその他のタスクは実行され続けます。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
したがって、この戦略はメインスレッドをブロックする可能性があります。
DiscardPolicyこの拒否ポリシーは比較的単純です。スレッド プールによって拒否されたタスクは、例外をスローしたり、Example を実行したりせずに、直接破棄されます。上記のコードを変更し、拒否ポリシーを DiscardPolicyThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( 2, 5, 10, TimeUnit.MICROSECONDS, new LinkedBlockingDeque<>(1), new ThreadPoolExecutor.CallerRunsPolicy());
goodsId:mobilephonethread name:pool-1- thread- に変更します。 1、実行: スレッド 0
実行結果から判断すると、6 つのタスクのみが実行され、他のタスクは放棄されました。
スレッド名: プール-1-スレッド-4、実行: スレッド 4
スレッド名: プール-1-スレッド-5、実行: スレッド 5
スレッド名: プール- 1-スレッド-3、実行: スレッド 3
スレッド名: プール-1-スレッド-2、実行: スレッド 1
スレッド名: プール-1-スレッド-1、実行: スレッド 2
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 サイトの他の関連記事を参照してください。

ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

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

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

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

ホットトピック









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

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

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

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

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