Java での ThreadPoolExecutor スレッド プールの使用法の概要
この記事では、Java での ThreadPoolExecutor スレッド プールの使用方法を紹介します。これには一定の参考値があります。必要な友人は参照してください。お役に立てば幸いです。
Executors
Executors は Java のツール クラスで、さまざまなタイプのスレッド プールを作成するためのファクトリ メソッドを提供します。
ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); cachedThreadPool.execute(new Runnable() { @Override public void run() { for (;;) { try { Thread.currentThread().sleep(1000); System.out.println(Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } } }); cachedThreadPool.execute(new Runnable() { @Override public void run() { for (;;) { try { Thread.currentThread().sleep(1000); System.out.println(Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } } });
ExecutorService cachedThreadPool = Executors.newFixedThreadPool(1);
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
for (;;) {
try {
Thread.currentThread().sleep(1000);
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
for (;;) {
try {
Thread.currentThread().sleep(1000);
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
ログイン後にコピー
newScheduledThreadPool は 3 秒に 1 回実行されます。 .
ExecutorService cachedThreadPool = Executors.newFixedThreadPool(1); cachedThreadPool.execute(new Runnable() { @Override public void run() { for (;;) { try { Thread.currentThread().sleep(1000); System.out.println(Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } } }); cachedThreadPool.execute(new Runnable() { @Override public void run() { for (;;) { try { Thread.currentThread().sleep(1000); System.out.println(Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } } });
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5); scheduledExecutorService.schedule(new Runnable() { @Override public void run() { for (;;) { try { Thread.currentThread().sleep(2000); System.out.println(Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } } }, 3, TimeUnit.SECONDS);
ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.execute(new Runnable() { @Override public void run() { for (;;) { try { System.out.println(Thread.currentThread().getName()); Thread.currentThread().sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } } } }); executorService.execute(new Runnable() { @Override public void run() { for (;;) { try { System.out.println(Thread.currentThread().getName()); Thread.currentThread().sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } } } });
/** * @author Hollis */ public class ExecutorsDemo { private static ExecutorService executor = Executors.newFixedThreadPool(15); public static void main(String[] args) { for (int i = 0; i JVM パラメーター: -Xmx8m -Xms8m を指定することにより、上記のコードを実行すると OOM がスローされます: <p></p><pre class="brush:php;toolbar:false">Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded at java.util.concurrent.LinkedBlockingQueue.offer(LinkedBlockingQueue.java:416) at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1371) at com.hollis.ExecutorsDemo.main(ExecutorsDemo.java:16)
ArrayBlockingQueue は配列で実装された境界付きブロッキング キューであり、容量を設定する必要があります。
public ArrayBlockingQueue(int capacity, boolean fair) { if (capacity <p>LinkedBlockingQueue はリンク リストで実装された境界付きブロッキング キューで、容量を設定できますオプションで、設定されていない場合は、最大長が Integer.MAX_VALUE の無制限のブロッキング キューになります。</p><pre class="brush:php;toolbar:false">public LinkedBlockingQueue() { this(Integer.MAX_VALUE); }
ここでの問題は、LinkedBlockingQueue の容量を設定しない場合、デフォルトの容量が Integer になることです。 MAX_VALUE.
NewFixedThreadPool に LinkedBlockingQueue を作成する場合、容量は指定されません。このとき、LinkedBlockingQueue は無制限のキューです。無制限のキューの場合、キューにタスクを継続的に追加できます。この場合、タスクが多すぎるため、メモリ オーバーフローの問題が発生している可能性があります。
newCachedThreadPool および newScheduledThreadPool によって作成されるスレッドの最大数は Integer.MAX_VALUE である可能性があり、非常に多くのスレッドを作成する可能性があります。原因 OOM.
ThreadPoolExecutor はスレッド プールを作成します
Executor を使用してスレッド プールを作成しないでください (主にデフォルト実装の使用を避けるため)。その後、ThreadPoolExecutor のコンストラクターを直接呼び出してスレッド プールを自分で作成できます。 BlockQueue の容量を指定するだけです。
ExecutorService executor = new ThreadPoolExecutor(10, 10, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue(10));
この場合、送信されたスレッドの数が現在使用可能なスレッドの数を超えると、java.util.concurrent.RejectedExecutionException がスローされます。これは、現在使用されているキューが原因です。スレッド プールは制限されたキューです。キューがいっぱいになると、新しいリクエストの処理を続行できません。
ThreadPoolExecutor を自分で定義することに加えて、Apache や guava などの他のメソッドもあります。
4 つのコンストラクター
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<runnable> workQueue) public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<runnable> workQueue, ThreadFactory threadFactory) public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<runnable> workQueue, RejectedExecutionHandler handler) public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)</runnable></runnable></runnable></runnable>
int corePoolSize => スレッド プール内のコア スレッドの最大数
スレッド プールが新しいスレッドを作成するとき、現在のスレッドの合計数が corePoolSize より小さい場合、新しいスレッド プールは新しいスレッドを作成します。これはコア スレッドです。corePoolSize を超えると、新しく作成された非コア スレッド
コア スレッドは、デフォルトでは、たとえコアスレッドは何もしません (アイドル状態)。
如果指定 ThreadPoolExecutor 的 allowCoreThreadTimeOut 这个属性为 true, 那么核心线程如果不干活(闲置状态)的话, 超过一定时间(时长下面参数决定), 就会被销毁掉
很好理解吧, 正常情况下你不干活我也养你, 因为我总有用到你的时候, 但有时候特殊情况(比如我自己都养不起了), 那你不干活我就要把你干掉了
int maximumPoolSize
该线程池中线程总数最大值
线程总数 = 核心线程数 + 非核心线程数.
long keepAliveTime
该线程池中非核心线程闲置超时时长
一个非核心线程, 如果不干活(闲置状态)的时长超过这个参数所设定的时长, 就会被销毁掉
如果设置 allowCoreThreadTimeOut = true, 则会作用于核心线程
TimeUnit unit
keepAliveTime的单位, TimeUnit是一个枚举类型, 其包括:
TimeUnit.DAYS; //天 TimeUnit.HOURS; //小时 TimeUnit.MINUTES; //分钟 TimeUnit.SECONDS; //秒 TimeUnit.MILLISECONDS; //毫秒 TimeUnit.MICROSECONDS; //微妙 TimeUnit.NANOSECONDS; //纳秒
BlockingQueue workQueue
一个阻塞队列, 用来存储等待执行的任务. 也就是说现在有10个任务, 核心线程 有四个, 非核心线程有六个, 那么这六个线程会被添加到 workQueue 中, 等待执行.
这个参数的选择也很重要, 会对线程池的运行过程产生重大影响, 一般来说, 这里的阻塞队列有以下几种选择:
SynchronousQueue: 这个队列接收到任务的时候, 会直接提交给线程处理, 而不保留它, 如果所有线程都在工作怎么办? 那就*新建一个线程来处理这个任务!所以为了保证不出现的错误, 使用这个类型队列的时候, maximumPoolSize 一般指定成 Integer.MAX_VALUE, 即无限大.
LinkedBlockingQueue: 这个队列接收到任务的时候, 如果当前线程数小于核心线程数, 则核心线程处理任务; 如果当前线程数等于核心线程数, 则进入队列等待. 由于这个队列最大值为 Integer.MAX_VALUE , 即所有超过核心线程数的任务都将被添加到队列中,这也就导致了 maximumPoolSize 的设定失效, 因为总线程数永远不会超过 corePoolSize.
ArrayBlockingQueue: 可以限定队列的长度, 接收到任务的时候, 如果没有达到 corePoolSize 的值, 则核心线程执行任务, 如果达到了, 则入队等候, 如果队列已满, 则新建线程(非核心线程)执行任务, 又如果总线程数到了maximumPoolSize, 并且队列也满了, 则发生错误.
DelayQueue: 队列内元素必须实现 Delayed 接口, 这就意味着你传进去的任务必须先实现Delayed接口. 这个队列接收到任务时, 首先先入队, 只有达到了指定的延时时间, 才会执行任务.
ThreadFactory threadFactory
它是ThreadFactory类型的变量, 用来创建新线程.
默认使用 Executors.defaultThreadFactory()
来创建线程. 使用默认的 ThreadFactory
来创建线程时, 会使新创建的线程具有相同的 NORM_PRIORITY
优先级并且是非守护线程, 同时也设置了线程的名称.
RejectedExecutionHandler handler
表示当拒绝处理任务时的策略, 有以下四种取值:
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常(默认). ThreadPoolExecutor.DiscardPolicy:直接丢弃任务, 但是不抛出异常. ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务, 然后重新尝试执行任务(重复此过程) ThreadPoolExecutor.CallerRunsPolicy:用调用者所在的线程来执行任务.
【相关推荐:Java视频教程】
以上が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 のアームストロング番号に関するガイド。ここでは、Java でのアームストロング数の概要とコードの一部について説明します。

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

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

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