Androidステップアップ-スレッドプール
4821 ワード
前回の記事(なぜ学ぶのか)でAsyncTaskの原理がスレッドプールに言及されたので、Androidを学ぶスレッドプールを学びましょう.では、スレッドプールにどのような利点があるのか、あるいはなぜスレッドプールを学ぶのかを見てみましょう.は、スレッドプール内のスレッドを再利用し、スレッドの新規作成と破棄のメモリオーバーヘッドを回避します. は、スレッドプールの最大同時数を有効にし、大量のスレッド間でシステムリソースを奪い合い、ブロック現象を回避することができる. は、スレッドを簡単に管理し、タイミング実行や指定間隔ループ実行などの機能を提供することができる.
ベーススレッドプール
よく使われるスレッドプールはたくさんありますが、まずベーススレッドプールThreadPoolExcutorを見てみましょう.他の一般的なスレッドプールはThreadPoolExcutorに基づいて実現されています.では、まずその構造方法から始めましょう.
パラメータ:corePoolSizeスレッドプールのコアスレッド数.デフォルトでは、スレッドがアイドル状態であっても、コアスレッドは常に存在します.パラメータ:maximumPoolSizeスレッドプールに収容できる最大スレッド数は、コアスレッドが足りない場合、非コアスレッドを開いてタスクを処理し、maximumPoolSize=corePoolSize+非コアスレッド数パラメータ:keepAliveTime非コアスレッドがタスクを処理してアイドル状態にある場合、一定時間の範囲で再利用されなければ破棄されます.keepAliveTimeは前述した一定の時間範囲である.パラメータ:unitには時間範囲があり、もちろん時間の単位を決定します.このパラメータは時間範囲を記述するパラメータです.これは列挙パラメータで、よく使われています:TimeUnit.DAYS TimeUnit.HOURS TimeUnit.MINUTESパラメータ:workQueueスレッドプールのタスクキュー、スレッドプールのexcuteメソッドでコミットされたタスクがこのキューに入ります.パラメータ:threadFactoryスレッドプールに新しいスレッドを作成する方法-->newThread(Runnale r)
ThreadPoolExcutorがタスクを実行する際に概ね遵守するルール:スレッドプール内のスレッド数がコアスレッド数に達していない場合、タスク を実行するためにコアスレッドを新たに開きます.コアスレッドの数以上に達した場合、タスクキューに挿入され、 の実行を待つ.タスクキューがいっぱいになった場合、タスクを実行するために非コアスレッドが新たに開きます. スレッド数が最大値に達すると、タスクの実行が拒否されます.
OK、そんなにたくさん説明したのに実践しないで、次の例を見てみましょう.
共通スレッドプール
FixedThreadPoolコアスレッドのみのスレッドプールであり、スレッドは回収されず、タスクに迅速に応答でき、タスクキューにもサイズ制限がないことを意味します.FixedThreadPoolのインスタンス化方法:
例:
CachedThreadPoolこれはスレッド数が不確定なスレッドプールである、以下の実例化方法から分かるように、コアスレッドは0、非コアスレッドはIntegerである.MAX_VALUE、これは大きな数です.タイムアウトポリシーは60秒です.また、SynchronousQueueは、要素を格納できないキューです.つまり、新しいタスクがあるたびに、すぐにスレッドが開きます.すべてのタスクが完了すると、スレッドプールに0スレッドが存在する場合もあります.したがって、システムリソースはほとんど占有されません.CachedThreadPoolのインスタンス化方法:
例:
ScheduledThreadPoolは,コアスレッドが固定され,非コアスレッドが大きいスレッドプールであることを以下のインスタンス化法から示す.DEFAULT_KEEPALIVE_MILLIS=10 L、つまりタイムアウトポリシーは10ミリ秒です.インスタンス化方法:
例:
SingleThreadPoolは、次のインスタンス化方法から、このスレッドプールには、コアスレッドが1つしかないことがわかります.すべてのタスクが同じスレッドで実行されることを保証し、スレッド同期の問題を処理する必要がないという意味です.インスタンス化方法:
例:
まとめ
一連の学習に入ったことがあり、スレッドプールについても初歩的な理解があったが、理解は理解に帰し、実際の開発に応用する上で優位性があるのは別のことだ.もっと実際と結びつけなければなりません.
参考文献:『Android開発芸術探索』
ベーススレッドプール
よく使われるスレッドプールはたくさんありますが、まずベーススレッドプールThreadPoolExcutorを見てみましょう.他の一般的なスレッドプールはThreadPoolExcutorに基づいて実現されています.では、まずその構造方法から始めましょう.
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}
パラメータ:corePoolSizeスレッドプールのコアスレッド数.デフォルトでは、スレッドがアイドル状態であっても、コアスレッドは常に存在します.パラメータ:maximumPoolSizeスレッドプールに収容できる最大スレッド数は、コアスレッドが足りない場合、非コアスレッドを開いてタスクを処理し、maximumPoolSize=corePoolSize+非コアスレッド数パラメータ:keepAliveTime非コアスレッドがタスクを処理してアイドル状態にある場合、一定時間の範囲で再利用されなければ破棄されます.keepAliveTimeは前述した一定の時間範囲である.パラメータ:unitには時間範囲があり、もちろん時間の単位を決定します.このパラメータは時間範囲を記述するパラメータです.これは列挙パラメータで、よく使われています:TimeUnit.DAYS TimeUnit.HOURS TimeUnit.MINUTESパラメータ:workQueueスレッドプールのタスクキュー、スレッドプールのexcuteメソッドでコミットされたタスクがこのキューに入ります.パラメータ:threadFactoryスレッドプールに新しいスレッドを作成する方法-->newThread(Runnale r)
ThreadPoolExcutorがタスクを実行する際に概ね遵守するルール:
OK、そんなにたくさん説明したのに実践しないで、次の例を見てみましょう.
mExecutor = new ThreadPoolExecutor(3, 6, 1, TimeUnit.SECONDS, new ArrayBlockingQueue(5));// mExecutor
fab.setOnClickListener(new View.OnClickListener() {//
@Override
public void onClick(View view) {
num++;
mExecutor.execute(new MyRunnable(String.valueOf(num)));
Log.d(TAG, " : "+String.valueOf(mExecutor.getPoolSize()));
Log.d(TAG, " : "+String.valueOf(mExecutor.getCompletedTaskCount()));
}
});
共通スレッドプール
FixedThreadPoolコアスレッドのみのスレッドプールであり、スレッドは回収されず、タスクに迅速に応答でき、タスクキューにもサイズ制限がないことを意味します.FixedThreadPoolのインスタンス化方法:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}
例:
ExecutorService e = Executors.newFixedThreadPool(5);
e.execute(new MyRunnable(String.valueOf(num)));
CachedThreadPoolこれはスレッド数が不確定なスレッドプールである、以下の実例化方法から分かるように、コアスレッドは0、非コアスレッドはIntegerである.MAX_VALUE、これは大きな数です.タイムアウトポリシーは60秒です.また、SynchronousQueueは、要素を格納できないキューです.つまり、新しいタスクがあるたびに、すぐにスレッドが開きます.すべてのタスクが完了すると、スレッドプールに0スレッドが存在する場合もあります.したがって、システムリソースはほとんど占有されません.CachedThreadPoolのインスタンス化方法:
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue());
}
例:
ExecutorService e2 = Executors.newCachedThreadPool();
e2.execute(new MyRunnable(String.valueOf(num)));
ScheduledThreadPoolは,コアスレッドが固定され,非コアスレッドが大きいスレッドプールであることを以下のインスタンス化法から示す.DEFAULT_KEEPALIVE_MILLIS=10 L、つまりタイムアウトポリシーは10ミリ秒です.インスタンス化方法:
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE,
DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
new DelayedWorkQueue());
}
例:
ExecutorService e3 = Executors.newScheduledThreadPool(5);
e3.execute(new MyRunnable(String.valueOf(num)));
SingleThreadPoolは、次のインスタンス化方法から、このスレッドプールには、コアスレッドが1つしかないことがわかります.すべてのタスクが同じスレッドで実行されることを保証し、スレッド同期の問題を処理する必要がないという意味です.インスタンス化方法:
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue()));
}
例:
ExecutorService e4 = Executors.newSingleThreadExecutor();
e4.execute(new MyRunnable(String.valueOf(num)));
まとめ
一連の学習に入ったことがあり、スレッドプールについても初歩的な理解があったが、理解は理解に帰し、実際の開発に応用する上で優位性があるのは別のことだ.もっと実際と結びつけなければなりません.
参考文献:『Android開発芸術探索』