AsyncTaskスレッドが死ぬことはありません


112

AsyncTaskユーザーがボタンを押したことに応答して、sを使用してデータをフェッチしています。これはうまく機能し、データのフェッチ中にインターフェイスの応答性を維持しますが、Eclipseデバッガーで何が行われているのかを確認したところ、新しいものAsyncTaskが作成されるたびに(多くの場合、一度しか使用できないため) )、新しいスレッドが作成されていましたが、終了されませんでした。

その結果、AsyncTaskそこに座っているだけで多数のスレッドができます。これが実際に問題であるかどうかはわかりませんが、これらの余分なスレッドを取り除きたいと思います。

これらのスレッドを強制終了するにはどうすればよいですか?


「終了しない」とはどういう意味ですか?タスクがdoInbackgroundメソッドを終了することはありませんか、それとも割り当てトレーカーにasynctaskオブジェクトが表示されるだけですか?
Francesco Laurita

7
doInBackgroundこの方法は完了しますが、スレッドがデバッグウィンドウに表示し続けます。例えば: Thread [<23> AsyncTask #4](Running)
Computerish

回答:


202

AsyncTaskで作成されたスレッドプールを管理しますThreadPoolExecutor。スレッド数は5〜128です。スレッドが5つを超える場合、それらの余分なスレッドは、削除される前に最大10秒間留まります。(注:これらの数値は現在表示されているオープンソースコードのものであり、Androidリリースによって異なります)。

AsyncTaskスレッドはそのままにしてください。


説明ありがとう!私は何も悪いことをしていないことを知ってうれしいです。好奇心から、なぜそのように設計されているのですか?すべてのメソッドが戻った後にスレッドを終了しないのはなぜですか?
Computerish

7
おそらく、後のリクエストでスレッドをフォークする時間を節約するためです。
CommonsWare

@CommonsWare私はAsyncTaskを実行して何らかの操作を実行し、ウィジェットボタンが押されたときにサービスが開始し、タスクが終了するとサービスをすぐに停止する必要がありますが、AsyncTaskが停止しないことがあります。どのように私はそれを止めるかを教えて
ハント

1
@SreekanthKarumanaghat:AsyncTask一般に、このように時間がかかるものにfor を使用することは悪い考えです。しかし、いいえ、余分なスレッドがなくなることについての私のコメントは、それらが未使用の場合です。したがって、6つのタスクのいずれかが終了すると、そのスレッドは10秒間プールに残り、その後そのスレッドは終了します。
CommonsWare 2018

1
@SreekanthKarumanaghat:「私の質問は、20の(たとえば)AsyncTaskを並列で実行するための制限があるかどうかです。」- AsyncTask今日を十分に活用することは、すばらしい計画ではありません。10秒以上実行される可能性のある20以上があることは、コードレビューに不合格となるはずです。20個のタスクを連続して作成すると、一度に実行されるのは数個だけで、残りは後で実行するためにキューに入れられます。一度に実行される数は、CPUのコアの数に基づいています。私の知る限り、現在のアルゴリズムは2N + 1の並列スレッドです。ここで、Nはコアの数です。
CommonsWare 2018

24

CommonsWareの応答に加えて:

現在、私はAndroid 2.2を使用しており、私のアプリケーションは常に1つだけのAsyncTaskを使用していますが、x分ごとに新しいものを作成しています。最初は新しいAsyncTaskスレッド(新しいAsyncTaskの新しいスレッド)が表示され始めますが、(CommonsWareで言及されているように)5つのスレッドの後は、デバッグウィンドウに表示されたままになり、新しいAsyncTaskスレッドが必要なときに再利用されます。デバッガーが切断されるまで、そこにとどまります。


2
はい、確認しました:表示されるAsyncTaskは5つ以下です。
セラフィムの

3

ここでも同じ症状です。私の場合、アクティビティを終了した後にスレッドがハングし、アプリが完全に終了することを期待していました。シングルスレッドのエグゼキューターを使用することで部分的に解決された問題:

    myActiveTask.executeOnExecutor(Executors.newSingleThreadExecutor());

これにより、作業が完了するとスレッドが消えます。


この答えにより、AsyncTaskは実行後に消えてしまいました。「Googleのやり方」ではないかもしれませんが、仕事は完了します。ありがとうございました。
Henrique de Sousa

これにより、単一スレッドでの非同期タスクの実行に関する私の特定の問題が解決されました。
法律Gimenez 2015年

0

ThreadPoolExecutorを使用します。

BlockingQueue workQueue= new LinkedBlockingQueue<Runnable>(100); // Work pool size
ThreadPoolExecutor executor = new ThreadPoolExecutor(
            Runtime.getRuntime().availableProcessors(),       // Initial pool size
            Runtime.getRuntime().availableProcessors(),       // Max pool size
            1, // KEEP_ALIVE_TIME
            TimeUnit.SECONDS, //  KEEP_ALIVE_TIME_UNIT
            workQueue);

execute()メソッドRunnableを使用してタスクを ポストします。

void execute (Runnable command)

指定されたタスクを将来実行します。タスクは新しいスレッドまたは既存のプールされたスレッドで実行される可能性があります

2番目のクエリについて:

これらのスレッドを強制終了するにはどうすればよいですか?

でのすべての作業が完了したらThreadPoolExecutor、以下の投稿で引用されているように適切にシャットダウンします。

Java ExecutorServiceを適切にシャットダウンする方法

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.