AsyncTaskは、doInBackground()からの実行にスレッドプールパターンを使用します。この問題は、最初(初期のAndroid OSバージョン)のプールサイズが1であったことを意味し、一連のAsyncTaskの並列計算がないことを意味します。しかし、後で修正し、サイズは5になりました。最大5つのAsyncTaskを同時に実行できます。残念ながら、どのバージョンで変更されたのか正確には覚えていません。
更新:
これは、現在の(2012-01-27)APIがこれについて言っていることです。
最初に導入されたとき、AsyncTasksは単一のバックグラウンドスレッドで順次実行されました。DONUTから、これはスレッドのプールに変更され、複数のタスクが並行して動作できるようになりました。HONEYCOMBの後で、並列実行によって引き起こされる一般的なアプリケーションエラーを回避するために、これを単一スレッドに戻すことが計画されています。本当に並列実行が必要な場合は、THREAD_POOL_EXECUTORでこのメソッドのexecuteOnExecutor(Executor、Params ...)バージョンを使用できます。ただし、その使用に関する警告については、解説を参照してください。
DONUTはAndroid 1.6、HONEYCOMBはAndroid 3.0です。
更新:2
kabuko
からのコメントを参照してくださいMar 7 2012 at 1:27
。
「複数のタスクを並行して実行できるスレッドのプール」が使用されているAPI(1.6から始まり、3.0で終わる)の場合、同時に実行されるAsyncTasksの数は、実行のために渡されたタスクの数によって異なりますが、doInBackground()
まだ終わっていません。
これは、2.2でテスト/確認済みです。で1秒スリープするカスタムAsyncTaskがあるとしますdoInBackground()
。AsyncTasksは、遅延したタスクを格納するために内部で固定サイズのキューを使用します。キューのサイズはデフォルトで10です。15個のカスタムタスクを続けて開始すると、最初の5個がに入るdoInBackground()
が、残りはキュー内で空きワーカースレッドを待機します。最初の5つのいずれかが終了してワーカースレッドが解放されるとすぐに、キューからのタスクが実行を開始します。したがって、この場合、最大5つのタスクが同時に実行されます。ただし、16個のカスタムタスクを続けて開始すると、最初の5個がに入りdoInBackground()
、残りの10個がキューに入れられますが、16日目は新しいワーカースレッドが作成されるため、すぐに実行が開始されます。したがって、この場合、最大6つのタスクが同時に実行されます。
同時に実行できるタスクの数には制限があります。以来AsyncTask
用途ワーカースレッド(128)と、アプリがでクラッシュします以上138個のカスタムタスクを実行しようとした場合、キューは、サイズ10を固定した遅延タスクの限定された最大数のスレッドプールエグゼキュータjava.util.concurrent.RejectedExecutionException
。
3.0以降のAPIでは、AsyncTask.executeOnExecutor(Executor exec, Params... params)
メソッドを介してカスタムスレッドプールエグゼキューターを使用できます。これにより、たとえば、デフォルトの10が必要でない場合に、遅延タスクキューのサイズを設定できます。
@Knossosが言及しているように、AsyncTaskCompat.executeParallel(task, params);
APIレベルに煩わされることなくタスクを並行して実行するために、サポートv.4ライブラリから使用するオプションがあります。このメソッドは、APIレベル26.0.0で廃止されました。
更新:3
これは、シリアル実行とパラレル実行のタスクの数を試す簡単なテストアプリです。https://github.com/vitkhudenko/test_asynctask
更新:4(これを指摘してくれた@penkzhouに感謝)
Android 4.4以降のAsyncTask
動作は、UPDATE:2セクションで説明したものとは異なります。あまりにも多くのスレッドを作成しないようにする修正がありAsyncTask
ます。
Android 4.4(API 19)より前のバージョンにAsyncTask
は、次のフィールドがありました。
private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;
private static final BlockingQueue<Runnable> sPoolWorkQueue =
new LinkedBlockingQueue<Runnable>(10);
Android 4.4(API 19)では、上記のフィールドは次のように変更されています。
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
private static final BlockingQueue<Runnable> sPoolWorkQueue =
new LinkedBlockingQueue<Runnable>(128);
この変更により、キューのサイズが128アイテムに増加し、スレッドの最大数がCPUコアの数* 2 + 1に減少します。アプリは引き続き同じ数のタスクを送信できます。