Java 4種類のスレッドプールnewCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor
new Threadの弊害とJavaの4種類のスレッドプールの使用を紹介し、Androidにも適用します.本文は基礎編で、後でラインオフプールのいくつかの高級機能を共有します.
1、new Threadの弊害非同期タスクを実行するあなたはまだ以下のnew Threadにすぎませんか?
では、あなたはoutが多すぎます.new Threadの弊害は以下の通りです.
a.new Threadの新規オブジェクトは毎回性能が悪い.b.スレッドは統一管理が欠けており、新規スレッドを無制限に作成し、互いに競争し、システムリソースを過剰に占有してハングアップまたはoomを招く可能性がある.c.タイミング実行、定期実行、スレッド中断など、より多くの機能が欠けている.Javaが提供する4つのスレッドプールの利点は、new Threadと比較して、a.存在するスレッドを再利用し、オブジェクトの作成、消滅のオーバーヘッドを低減し、パフォーマンスが優れていることです.b.最大同時スレッド数を効果的に制御し、システム資源の使用率を高めると同時に、多すぎる資源競争を避け、渋滞を避けることができる.c.タイミング実行、定期実行、単一スレッド、同時数制御などの機能を提供する.
2、Javaスレッドプール
JavaはExecutorsを通じて4種類のスレッドプールを提供し、それぞれ:newCachedThreadPoolはキャッシュ可能なスレッドプールを作成し、スレッドプールの長さが処理の必要を超えた場合、空きスレッドを柔軟に回収することができ、回収可能でない場合、新しいスレッドを作成する.新FixedThreadPoolは、スレッドの最大同時数を制御し、超過したスレッドがキュー内で待機する定長スレッドプールを作成します.新ScheduledThreadPoolは、タイミングおよび周期的なタスク実行をサポートする定長スレッドプールを作成します.新SingleThreadExecutorは、一意の作業スレッドのみでタスクを実行し、すべてのタスクが指定された順序(FIFO、LIFO、優先度)で実行されることを保証する単一スレッド化されたスレッドプールを作成します.
(1).newCachedThreadPoolはキャッシュ可能スレッドプールを作成し、スレッドプールの長さが処理の必要を超えた場合、空きスレッドを柔軟に回収し、回収可能でない場合、新しいスレッドを作成する.サンプルコードは次のとおりです.
スレッドプールは無限大で、2番目のタスクを実行するたびに最初のタスクが完了し、新しいスレッドを作成するのではなく、最初のタスクを実行するスレッドが多重化されます.
(2).newFixedThreadPoolは、スレッドの最大同時数を制御し、超過したスレッドがキュー内で待機する定長スレッドプールを作成します.サンプルコードは次のとおりです.
スレッドプールのサイズが3で、タスクごとにindexを出力した後sleepは2秒なので、2秒ごとに3つの数字を印刷します.
定長スレッドプールのサイズは、システムリソースに基づいて設定することが望ましい.Runtime.getRuntime().availableProcessors().PreloadDataCacheを参照してください.
(3)newScheduledThreadPoolは、タイミングおよび周期的なタスク実行をサポートする定長スレッドプールを作成します.遅延実行例コードは次のとおりです.
3秒遅れて実行することを示します.
定期的に実行するサンプルコードは次のとおりです.
1秒遅れて3秒ごとに実行されることを示します.
ScheduledExecutorServiceはTimerよりも安全で、機能が強く、後で単独で比較する記事があります.
(4)、newSingleThreadExecutorは、指定された順序(FIFO、LIFO、優先度)ですべてのタスクが実行されるように、一意の作業スレッドでのみタスクを実行する単一スレッド化されたスレッドプールを作成します.サンプルコードは次のとおりです.
結果は順次出力され,各タスクを順次実行することに相当する.
現行のGUIプログラムの多くは単一スレッドです.Androidの単一スレッドは、データベース操作、ファイル操作、アプリケーションの一括インストール、アプリケーションの一括削除など、同時実行には適していませんが、IOブロック性やUIスレッドの応答に影響を与える操作に使用できます.
スレッドプールの役割:
スレッドプールの役割は、システムで実行されるスレッドの数を制限することです. システムの環境状況に応じて、スレッドの数を自動的にまたは手動で設定し、実行の最適な効果を達成することができます.システム資源の浪費が少なく、システムの混雑効率が高くない.スレッドプールでスレッド数を制御し、他のスレッドが並んで待機します.1つのタスクの実行が完了し、キューから先頭のタスクを取り出して実行を開始します.キューにプロセスが待機していない場合、スレッドプールのこのリソースは待機しています.新しいタスクが実行される必要がある場合、スレッドプールに待機している作業スレッドがあれば、実行を開始できます.そうでなければ待機キューに入ります.
スレッドプールを使用する理由:
1.スレッドの作成と破棄の回数を減らし、各ワークスレッドを再利用し、複数のタスクを実行できます.
2.システムの耐え忍ぶ能力によって、スレッドプールの中の作業ラインのスレッドの数を調整することができて、多すぎるメモリを消費するため、サーバーを疲れて伏せることを防止します(各スレッドは約1 MBのメモリを必要として、スレッドが開くのが多ければ多いほど、消費するメモリも大きくなって、最後にハングアップします).
JavaのスレッドプールのトップレベルのインタフェースはExecutorですが、厳密にはExecutorはスレッドプールではなく、スレッドを実行するツールにすぎません.本格的なスレッドプールインタフェースはExecutorServiceです.
重要なクラス:
ExecutorService
本格的なスレッドプールインタフェース.
ScheduledExecutorService
Timer/TimerTaskと同様に、タスクの繰り返しが必要な問題を解決できます.
ThreadPoolExecutor
ExecutorServiceのデフォルト実装.
ScheduledThreadPoolExecutor
ThreadPoolExecutorのScheduledExecutorServiceインタフェース実装、周期的タスクスケジューリングのクラス実装を継承します.
スレッドプールを構成するのは複雑で、特にスレッドプールの原理がよく分からない場合、構成可能なスレッドプールが優れていないため、Executorsクラスに静的な工場を提供し、一般的なスレッドプールを生成します.
1. newSingleThreadExecutor
単一スレッドのスレッドプールを作成します.このスレッドプールでは、1つのスレッドのみが動作します.つまり、1つのスレッドがすべてのタスクをシリアルで実行することに相当します.この唯一のスレッドが異常に終了した場合、新しいスレッドが置き換えられます.このスレッドプールは、すべてのタスクの実行順序がタスクのコミット順序で実行されることを保証します.
2.newFixedThreadPool
固定サイズのスレッドプールを作成します.タスクをコミットするたびに、スレッドがスレッドプールの最大サイズに達するまでスレッドが作成されます.スレッドプールのサイズは、最大値に達すると変更されず、実行異常によってスレッドが終了すると、スレッドプールに新しいスレッドが追加されます.
3. newCachedThreadPool
キャッシュ可能なスレッドプールを作成します.スレッドプールのサイズがタスクの処理に必要なスレッドを超えている場合、
これにより、空き(60秒でタスクを実行しない)スレッドの一部が回収され、タスク数が増加すると、このスレッドプールは新しいスレッドをスマートに追加してタスクを処理することができます.このスレッドプールはスレッドプールのサイズに制限はありません.スレッドプールのサイズは、オペレーティングシステム(またはJVM)が作成できる最大スレッドサイズに完全に依存します.
4.newScheduledThreadPool
無限のサイズのスレッドプールを作成します.このスレッド・プールは、タイミングおよび周期的なタスク実行の要件をサポートします.
≪インスタンス|Instance|emdw≫
1:newSingleThreadExecutor·
MyThread.java
TestSingleThreadExecutor.java
出力結果
2:newFixedThreadPool
TestFixedThreadPool.Java
出力結果
3:newCachedThreadPool
TestCachedThreadPool.java
出力結果:
4:newScheduledThreadPool
TestScheduledThreadPoolExecutor.java
出力結果
変換元:https://www.cnblogs.com/zhujiabin/p/5404771.html
1、new Threadの弊害非同期タスクを実行するあなたはまだ以下のnew Threadにすぎませんか?
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
}
}).start();
では、あなたはoutが多すぎます.new Threadの弊害は以下の通りです.
a.new Threadの新規オブジェクトは毎回性能が悪い.b.スレッドは統一管理が欠けており、新規スレッドを無制限に作成し、互いに競争し、システムリソースを過剰に占有してハングアップまたはoomを招く可能性がある.c.タイミング実行、定期実行、スレッド中断など、より多くの機能が欠けている.Javaが提供する4つのスレッドプールの利点は、new Threadと比較して、a.存在するスレッドを再利用し、オブジェクトの作成、消滅のオーバーヘッドを低減し、パフォーマンスが優れていることです.b.最大同時スレッド数を効果的に制御し、システム資源の使用率を高めると同時に、多すぎる資源競争を避け、渋滞を避けることができる.c.タイミング実行、定期実行、単一スレッド、同時数制御などの機能を提供する.
2、Javaスレッドプール
JavaはExecutorsを通じて4種類のスレッドプールを提供し、それぞれ:newCachedThreadPoolはキャッシュ可能なスレッドプールを作成し、スレッドプールの長さが処理の必要を超えた場合、空きスレッドを柔軟に回収することができ、回収可能でない場合、新しいスレッドを作成する.新FixedThreadPoolは、スレッドの最大同時数を制御し、超過したスレッドがキュー内で待機する定長スレッドプールを作成します.新ScheduledThreadPoolは、タイミングおよび周期的なタスク実行をサポートする定長スレッドプールを作成します.新SingleThreadExecutorは、一意の作業スレッドのみでタスクを実行し、すべてのタスクが指定された順序(FIFO、LIFO、優先度)で実行されることを保証する単一スレッド化されたスレッドプールを作成します.
(1).newCachedThreadPoolはキャッシュ可能スレッドプールを作成し、スレッドプールの長さが処理の必要を超えた場合、空きスレッドを柔軟に回収し、回収可能でない場合、新しいスレッドを作成する.サンプルコードは次のとおりです.
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
final int index = i;
try {
Thread.sleep(index * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(index);
}
});
}
スレッドプールは無限大で、2番目のタスクを実行するたびに最初のタスクが完了し、新しいスレッドを作成するのではなく、最初のタスクを実行するスレッドが多重化されます.
(2).newFixedThreadPoolは、スレッドの最大同時数を制御し、超過したスレッドがキュー内で待機する定長スレッドプールを作成します.サンプルコードは次のとおりです.
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
final int index = i;
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(index);
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
スレッドプールのサイズが3で、タスクごとにindexを出力した後sleepは2秒なので、2秒ごとに3つの数字を印刷します.
定長スレッドプールのサイズは、システムリソースに基づいて設定することが望ましい.Runtime.getRuntime().availableProcessors().PreloadDataCacheを参照してください.
(3)newScheduledThreadPoolは、タイミングおよび周期的なタスク実行をサポートする定長スレッドプールを作成します.遅延実行例コードは次のとおりです.
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
scheduledThreadPool.schedule(new Runnable() {
@Override
public void run() {
System.out.println("delay 3 seconds");
}
}, 3, TimeUnit.SECONDS);
3秒遅れて実行することを示します.
定期的に実行するサンプルコードは次のとおりです.
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("delay 1 seconds, and excute every 3 seconds");
}
}, 1, 3, TimeUnit.SECONDS);
1秒遅れて3秒ごとに実行されることを示します.
ScheduledExecutorServiceはTimerよりも安全で、機能が強く、後で単独で比較する記事があります.
(4)、newSingleThreadExecutorは、指定された順序(FIFO、LIFO、優先度)ですべてのタスクが実行されるように、一意の作業スレッドでのみタスクを実行する単一スレッド化されたスレッドプールを作成します.サンプルコードは次のとおりです.
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
final int index = i;
singleThreadExecutor.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(index);
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
結果は順次出力され,各タスクを順次実行することに相当する.
現行のGUIプログラムの多くは単一スレッドです.Androidの単一スレッドは、データベース操作、ファイル操作、アプリケーションの一括インストール、アプリケーションの一括削除など、同時実行には適していませんが、IOブロック性やUIスレッドの応答に影響を与える操作に使用できます.
スレッドプールの役割:
スレッドプールの役割は、システムで実行されるスレッドの数を制限することです. システムの環境状況に応じて、スレッドの数を自動的にまたは手動で設定し、実行の最適な効果を達成することができます.システム資源の浪費が少なく、システムの混雑効率が高くない.スレッドプールでスレッド数を制御し、他のスレッドが並んで待機します.1つのタスクの実行が完了し、キューから先頭のタスクを取り出して実行を開始します.キューにプロセスが待機していない場合、スレッドプールのこのリソースは待機しています.新しいタスクが実行される必要がある場合、スレッドプールに待機している作業スレッドがあれば、実行を開始できます.そうでなければ待機キューに入ります.
スレッドプールを使用する理由:
1.スレッドの作成と破棄の回数を減らし、各ワークスレッドを再利用し、複数のタスクを実行できます.
2.システムの耐え忍ぶ能力によって、スレッドプールの中の作業ラインのスレッドの数を調整することができて、多すぎるメモリを消費するため、サーバーを疲れて伏せることを防止します(各スレッドは約1 MBのメモリを必要として、スレッドが開くのが多ければ多いほど、消費するメモリも大きくなって、最後にハングアップします).
JavaのスレッドプールのトップレベルのインタフェースはExecutorですが、厳密にはExecutorはスレッドプールではなく、スレッドを実行するツールにすぎません.本格的なスレッドプールインタフェースはExecutorServiceです.
重要なクラス:
ExecutorService
本格的なスレッドプールインタフェース.
ScheduledExecutorService
Timer/TimerTaskと同様に、タスクの繰り返しが必要な問題を解決できます.
ThreadPoolExecutor
ExecutorServiceのデフォルト実装.
ScheduledThreadPoolExecutor
ThreadPoolExecutorのScheduledExecutorServiceインタフェース実装、周期的タスクスケジューリングのクラス実装を継承します.
スレッドプールを構成するのは複雑で、特にスレッドプールの原理がよく分からない場合、構成可能なスレッドプールが優れていないため、Executorsクラスに静的な工場を提供し、一般的なスレッドプールを生成します.
1. newSingleThreadExecutor
単一スレッドのスレッドプールを作成します.このスレッドプールでは、1つのスレッドのみが動作します.つまり、1つのスレッドがすべてのタスクをシリアルで実行することに相当します.この唯一のスレッドが異常に終了した場合、新しいスレッドが置き換えられます.このスレッドプールは、すべてのタスクの実行順序がタスクのコミット順序で実行されることを保証します.
2.newFixedThreadPool
固定サイズのスレッドプールを作成します.タスクをコミットするたびに、スレッドがスレッドプールの最大サイズに達するまでスレッドが作成されます.スレッドプールのサイズは、最大値に達すると変更されず、実行異常によってスレッドが終了すると、スレッドプールに新しいスレッドが追加されます.
3. newCachedThreadPool
キャッシュ可能なスレッドプールを作成します.スレッドプールのサイズがタスクの処理に必要なスレッドを超えている場合、
これにより、空き(60秒でタスクを実行しない)スレッドの一部が回収され、タスク数が増加すると、このスレッドプールは新しいスレッドをスマートに追加してタスクを処理することができます.このスレッドプールはスレッドプールのサイズに制限はありません.スレッドプールのサイズは、オペレーティングシステム(またはJVM)が作成できる最大スレッドサイズに完全に依存します.
4.newScheduledThreadPool
無限のサイズのスレッドプールを作成します.このスレッド・プールは、タイミングおよび周期的なタスク実行の要件をサポートします.
≪インスタンス|Instance|emdw≫
1:newSingleThreadExecutor·
MyThread.java
public class MyThread extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 。。。");
}
}
TestSingleThreadExecutor.java
public class TestSingleThreadExecutor {
public static void main(String[] args) {
//
ExecutorService pool = Executors. newSingleThreadExecutor();
// Runnable ,Thread Runnable
Thread t1 = new MyThread();
Thread t2 = new MyThread();
Thread t3 = new MyThread();
Thread t4 = new MyThread();
Thread t5 = new MyThread();
//
pool.execute(t1);
pool.execute(t2);
pool.execute(t3);
pool.execute(t4);
pool.execute(t5);
//
pool.shutdown();
}
}
出力結果
pool-1-thread-1 。。。
pool-1-thread-1 。。。
pool-1-thread-1 。。。
pool-1-thread-1 。。。
pool-1-thread-1 。。。
2:newFixedThreadPool
TestFixedThreadPool.Java
publicclass TestFixedThreadPool {
publicstaticvoid main(String[] args) {
//
ExecutorService pool = Executors.newFixedThreadPool(2);
// Runnable ,Thread Runnable
Thread t1 = new MyThread();
Thread t2 = new MyThread();
Thread t3 = new MyThread();
Thread t4 = new MyThread();
Thread t5 = new MyThread();
//
pool.execute(t1);
pool.execute(t2);
pool.execute(t3);
pool.execute(t4);
pool.execute(t5);
//
pool.shutdown();
}
}
出力結果
pool-1-thread-1 。。。
pool-1-thread-2 。。。
pool-1-thread-1 。。。
pool-1-thread-2 。。。
pool-1-thread-1 。。。
3:newCachedThreadPool
TestCachedThreadPool.java
public class TestCachedThreadPool {
public static void main(String[] args) {
//
ExecutorService pool = Executors.newCachedThreadPool();
// Runnable ,Thread Runnable
Thread t1 = new MyThread();
Thread t2 = new MyThread();
Thread t3 = new MyThread();
Thread t4 = new MyThread();
Thread t5 = new MyThread();
//
pool.execute(t1);
pool.execute(t2);
pool.execute(t3);
pool.execute(t4);
pool.execute(t5);
//
pool.shutdown();
}
}
出力結果:
pool-1-thread-2 。。。
pool-1-thread-4 。。。
pool-1-thread-3 。。。
pool-1-thread-1 。。。
pool-1-thread-5 。。。
4:newScheduledThreadPool
TestScheduledThreadPoolExecutor.java
public class TestScheduledThreadPoolExecutor {
public static void main(String[] args) {
ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
exec.scheduleAtFixedRate(new Runnable() {//
@Override
public void run() {
//throw new RuntimeException();
System.out.println("================");
}
}, 1000, 5000, TimeUnit.MILLISECONDS);
exec.scheduleAtFixedRate(new Runnable() {// ,
@Override
public void run() {
System.out.println(System.nanoTime());
}
}, 1000, 2000, TimeUnit.MILLISECONDS);
}
}
出力結果
================
8384644549516
8386643829034
8388643830710
================
8390643851383
8392643879319
8400643939383
変換元:https://www.cnblogs.com/zhujiabin/p/5404771.html