Androidスレッドプールはこう使います
8842 ワード
背景
前にスレッドとマルチスレッドについて2つの文章を書いて、意外にもマルチスレッドを書いて、それはスレッドプールが欠かせないに違いありません.もしスレッドとスレッドプールの知識を知りたいなら、私が前に書いたスレッドを見てもいいです.あなたは本当にそれを知っていますか.これが本当のマルチスレッドです.では、スレッドプールとは何ですか.どんなメリットがありますか.1.スレッドプール内のスレッドを再利用し、スレッドの作成と破棄によるパフォーマンスオーバーヘッドを回避します.スレッドプールの最大同時数を効果的に制御し、大量のスレッド間でシステムリソースを奪い合うことによるスレッドの詰まりを回避できます.2.スレッドを簡単に管理でき、タイミング実行や指定間隔ループ実行などの機能を提供できる.3.AsyncTaskに比べて、最大の利点は、スレッドが制御可能であることです.たとえば、ページを離れると、AsyncTaskにコミットできないタスクは取り消すことができず、スレッドプールは不要なときにスレッドを削除することができます.
スレッドプールとは
では、スレッドプールはどのように作成すればいいのでしょうか.まず、スレッドプールの作成方法を見てみましょう.
まず各パラメータの意味を見てみましょう.1.corePoolSize:コアプールのサイズは、スレッドプールを作成した後、デフォルトでは、スレッドプールにはスレッドがありません.タスクが来るのを待ってスレッドを作成してタスクを実行します.スレッドプールのスレッド数がcorePoolSizeに達すると、到着したタスクをキャッシュキューに入れます.この数を超えるスレッドは、ワークキューがいっぱいになった場合にのみ作成されます.スレッドの空き時間がアクティブ時間を超えている場合は、回収可能としてマークされ、スレッドプールの現在のサイズがcorePoolSizeを超えている場合にのみスレッドが終了します.ユーザはprestartAllCoreThreads()またはprestartCoreThread()メソッドを呼び出してスレッドを事前に作成することができます.すなわち、タスクが来ない前にcorePoolSizeスレッドまたはスレッドを作成します. maximumPoolSize:スレッドプールの最大スレッド数、このパラメータも非常に重要なパラメータであり、オンライン・プログラム・プールで最大何個のスレッドを作成できるかを示します.この値より大きい場合、Threadは廃棄処理機構によって処理される. keepAliveTime:スレッドがタスク実行されていない場合、最大どのくらいの時間で終了するかを示します.デフォルトでは、スレッドプール内のスレッド数がcorePoolSizeより大きい場合にのみ、keepAliveTimeは、スレッドプール内のスレッド数がcorePoolSizeより大きくないまで機能します.すなわち、スレッドプール内のスレッド数がcorePoolSizeより大きい場合、1つのスレッドの空き時間がkeepAliveTimeに達すると、スレッドプール内のスレッド数がcorePoolSizeを超えないまで終了します.しかしallowCoreThreadTimeOut(boolean)メソッドが呼び出されると、オンライン・スレッド・プールのスレッド数がcorePoolSizeより大きくない場合、keepAliveTimeパラメータもスレッド・プールのスレッド数が0になるまで機能します. Unit:パラメータkeepAliveTimeの時間単位で、7種類の値が取り、TimeUnitクラスには7種類の静的属性があります. workQueue:実行待ちのタスクを格納するブロックキューで、スレッドプール内のスレッド数がcorePoolSizeに達すると、到着したタスクをキャッシュキューに格納します. threadFactory:スレッドファクトリ、主にスレッドの作成に使用されます. handler:タスクの処理を拒否した場合のポリシー、すなわちパラメータmaximumPoolSizeが到達した後に処理を破棄する方法を示す.次の4つの値があります.AbortPolicy:タスクを破棄し、RejectedExecutionException例外を放出します.ThreadPoolExecutor.DiscardPolicy:タスクも破棄されますが、例外は放出されません.ThreadPoolExecutor.DiscardOldestPolicy:キューの一番前のタスクを破棄し、タスクの実行を再試行します(この手順を繰り返します).CallerRunsPolicy:このタスクを呼び出しスレッドで処理するユーザーは、インタフェースRejectedExecutionHandlerが独自のポリシーをカスタマイズすることもできます.
スレッドプールDemo
これはネット上で探している簡単なスレッドプールの実装コードです.
動的エージェントを使用してThreadPoolProxyFactoryを作成します.スレッドプールを取得するには、通常のスレッドプールとダウンロードしたスレッドプールの2つの方法があります.
スレッドプールエージェントは、スレッドプールの代わりにいくつかの操作を完了します.タスクの実行、タスクのコミット、タスクの削除の3つの方法があります.
では、スレッドプールをどのように使用しますか.
まとめ
これは多分Androidスレッドプールの使用ですが、何か悪いところがあったらメッセージを歓迎します.私たちは一緒に交流して、みんなを書きます.優先度スレッドプールの実装に興味のある友人も、優先度スレッドプールの実装を学ぶことができます.
前にスレッドとマルチスレッドについて2つの文章を書いて、意外にもマルチスレッドを書いて、それはスレッドプールが欠かせないに違いありません.もしスレッドとスレッドプールの知識を知りたいなら、私が前に書いたスレッドを見てもいいです.あなたは本当にそれを知っていますか.これが本当のマルチスレッドです.では、スレッドプールとは何ですか.どんなメリットがありますか.1.スレッドプール内のスレッドを再利用し、スレッドの作成と破棄によるパフォーマンスオーバーヘッドを回避します.スレッドプールの最大同時数を効果的に制御し、大量のスレッド間でシステムリソースを奪い合うことによるスレッドの詰まりを回避できます.2.スレッドを簡単に管理でき、タイミング実行や指定間隔ループ実行などの機能を提供できる.3.AsyncTaskに比べて、最大の利点は、スレッドが制御可能であることです.たとえば、ページを離れると、AsyncTaskにコミットできないタスクは取り消すことができず、スレッドプールは不要なときにスレッドを削除することができます.
スレッドプールとは
では、スレッドプールはどのように作成すればいいのでしょうか.まず、スレッドプールの作成方法を見てみましょう.
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
まず各パラメータの意味を見てみましょう.1.corePoolSize:コアプールのサイズは、スレッドプールを作成した後、デフォルトでは、スレッドプールにはスレッドがありません.タスクが来るのを待ってスレッドを作成してタスクを実行します.スレッドプールのスレッド数がcorePoolSizeに達すると、到着したタスクをキャッシュキューに入れます.この数を超えるスレッドは、ワークキューがいっぱいになった場合にのみ作成されます.スレッドの空き時間がアクティブ時間を超えている場合は、回収可能としてマークされ、スレッドプールの現在のサイズがcorePoolSizeを超えている場合にのみスレッドが終了します.ユーザはprestartAllCoreThreads()またはprestartCoreThread()メソッドを呼び出してスレッドを事前に作成することができます.すなわち、タスクが来ない前にcorePoolSizeスレッドまたはスレッドを作成します.
スレッドプールDemo
これはネット上で探している簡単なスレッドプールの実装コードです.
動的エージェントを使用してThreadPoolProxyFactoryを作成します.スレッドプールを取得するには、通常のスレッドプールとダウンロードしたスレッドプールの2つの方法があります.
public class ThreadPoolProxyFactory {
static ThreadPoolProxy mNormalThreadPoolProxy;
static ThreadPoolProxy mDownLoadThreadPoolProxy;
/**
* mNormalThreadPoolProxy
*/
public static ThreadPoolProxy getNormalThreadPoolProxy() {
if (mNormalThreadPoolProxy == null) {
synchronized (ThreadPoolProxyFactory.class) {
if (mNormalThreadPoolProxy == null) {
mNormalThreadPoolProxy = new ThreadPoolProxy(5, 5);
}
}
}
return mNormalThreadPoolProxy;
}
/**
* mDownLoadThreadPoolProxy
*/
public static ThreadPoolProxy getDownLoadThreadPoolProxy() {
if (mDownLoadThreadPoolProxy == null) {
synchronized (ThreadPoolProxyFactory.class) {
if (mDownLoadThreadPoolProxy == null) {
mDownLoadThreadPoolProxy = new ThreadPoolProxy(3, 3);
}
}
}
return mDownLoadThreadPoolProxy;
}
}
スレッドプールエージェントは、スレッドプールの代わりにいくつかの操作を完了します.タスクの実行、タスクのコミット、タスクの削除の3つの方法があります.
public class ThreadPoolProxy {
ThreadPoolExecutor mExecutor;
private int mCorePoolSize;
private int mMaximumPoolSize;
/**
* @param corePoolSize
* @param maximumPoolSize
*/
public ThreadPoolProxy(int corePoolSize, int maximumPoolSize) {
mCorePoolSize = corePoolSize;
mMaximumPoolSize = maximumPoolSize;
}
/**
* ThreadPoolExecutor
* , ,
*/
private void initThreadPoolExecutor() {
if (mExecutor == null || mExecutor.isShutdown() || mExecutor.isTerminated()) {
synchronized (ThreadPoolProxy.class) {
if (mExecutor == null || mExecutor.isShutdown() || mExecutor.isTerminated()) {
long keepAliveTime = 3000;
TimeUnit unit = TimeUnit.MILLISECONDS;
BlockingQueue workQueue = new LinkedBlockingDeque<>();
ThreadFactory threadFactory = Executors.defaultThreadFactory();
RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();
mExecutor = new ThreadPoolExecutor(mCorePoolSize, mMaximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, handler);
}
}
}
}
/**
?
1.
execute->
submit-->
2.Future ?
1. , get ,get
2.get ===>
*/
/**
*
*/
public void execute(Runnable task) {
initThreadPoolExecutor();
mExecutor.execute(task);
}
/**
*
*/
public Future submit(Runnable task) {
initThreadPoolExecutor();
return mExecutor.submit(task);
}
/**
*
*/
public void remove(Runnable task) {
initThreadPoolExecutor();
mExecutor.remove(task);
}
}
では、スレッドプールをどのように使用しますか.
ThreadPoolProxyFactory .getNormalThreadPoolProxy().execute(Runnable);
まとめ
これは多分Androidスレッドプールの使用ですが、何か悪いところがあったらメッセージを歓迎します.私たちは一緒に交流して、みんなを書きます.優先度スレッドプールの実装に興味のある友人も、優先度スレッドプールの実装を学ぶことができます.