Вопрос по java, threadpool, android, android-asynctask, multithreading – Какие изменения действительно произошли в Async Task после Android Gingerbread?

2

Какие изменения действительно внесла команда Android в задачу Async после android 2.3. Когда я выполнил следующий код, я получил одинаковый результат как в Android 2.3, так и в 3.0.

package com.sample.asynctask;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;

public class AsyncTaskTestActivity extends Activity {
    private static final String TAG = "AsyncTaskTestActivity";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        //ExecutorService executorService = Executors.newFixedThreadPool(1);
        for (int i = 1; i <= 20; i++) {
            TestTask testTask = new TestTask(i);
            testTask.execute();
        }
    }

    private static class TestTask extends AsyncTask<Void, Integer, Void> {
        int i;
        public TestTask(int i) {
            Log.i(TAG, "Constructor for " + i);
            this.i = i;
        }

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            super.onPreExecute();
            Log.i(TAG, "onPreExecute for " + i);
        }

        @Override
        protected Void doInBackground(Void... params) {
            Log.i(TAG, i + " Thread goes to sleep");
            try {
                Thread.sleep(20000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            Log.i(TAG, i + " Thread wakes up");
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
            Log.i(TAG, "onPostExecute for " + i);
        }
    }
}

Мое предположение в Gingerbread: 5 Асинхронная задача выполняется одновременно в одном пуле потоков. Мое предположение в Honeycomb: 1 Асинхронная задача выполняется одновременно в одном пуле потоков. Точно так же, как одновременное выполнение.

Но и Gingerbread, и Honeycomb выполняют 5 асинхронных задач одновременно.

А также, когда число задач Async увеличивается до 140. Я не получаюjava.util.concurrent.RejectedExecutionException .

Верны ли мои предположения? Что на самом деле происходит внутри?

Ваш Ответ

3   ответа
1

лена сотрудником Google, поэтому она заслуживает доверия.

https:?! //groups.google.com/forum/ fromgroups # тема / андроид-разработчиков / 8M0RTFfO7-M

3
Верны ли мои предположения?

Что там на самом деле происходит?

Исполнитель по умолчанию внутри Android.os.AsyncTask:

... ...

private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;

... ...

был сброшен в Android.app.ActivityThread:

... ...

// If the app is Honeycomb MR1 or earlier, switch its AsyncTask
// implementation to use the pool executor.  Normally, we use the
// serialized executor as the default. This has to happen in the
// main thread so the main looper is set right.
if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
    AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}

... ...
Какое изменение действительно произошло в Async Task после Android Gingerbread?

Проверьте AsyncTask история изменений, точнее, этот:

7 марта 2011 г. - AsyncTask теперь использует исполнителя опроса для приложений, использующих HC MR1 и т. Д.

Когда число для асинхронной задачи увеличено до 140, я не получаю java.util.concurrent.RejectedExecutionException.

Это коэффициент общего количества задач и времени выполнения для каждой задачи, в другом мире общее количество задач равно 140 (что больше 128), однако общее количество потоков, выделенных пулом потоков в любой момент времени, составляет меньше 128, иными словами, в вашем случае всегда есть несколько незанятых потоков (из-за последнего выполненного задания и ресурса освобождения). Вы можете попробовать увеличить время выполнения каждой задачи, напримерThread.sleep(10000), это, вероятно, даст вам RejectedExecutionException.

@ Ads, я отредактировал свой ответ. yorkw
и я не получаю сообщение об ошибке при выполнении более 140 асинхронных задач? Ads
if (data.appInfo.targetSdkVersion <= 12) {AsyncTask.setDefaultExecutor (AsyncTask.THREAD_POOL_EXECUTOR); } так что эти строки делают это изменение right.cool Ads
@ Ads, проще говоря, 140 задач не означают, что пулу потоков нужно выделять 140 потоков, на самом деле важно, сколько потоков выделено в любой момент времени, зависит от того, сколько времени занимает каждая задача, пулу потоков может понадобиться всего 10 потоков для запуска всех задач. , Если следующая задача отправлена, а в пуле потоков нет доступных потоков (все 128 потоков заняты), то пул потоков выдаст исключение RejectedExecutionException. yorkw
Да, сейчас я получаю исключение RejectedExecutionException. Но мне все еще не очень ясно об этом Ads
0

чтобы вы работали на ICS и выше с оборудованием.

Видеть:http: //commonsware.com/blog/2012/04/20/asynctask-threading-regression-confirmed.htm

Похожие вопросы