Получить ThreadPoolExecutor по умолчанию?

Я делаю приложение для Android, и у меня возникают проблемы с появлением RejectedExecutionException (вероятно, из-за чрезмерного использования AsyncTask). Я хотел бы получить ThreadPoolExecutor по умолчанию и прочитать getTaskCount() и getCompletedTaskCount().

Как получить экземпляр ThreadPoolExecutor, не создавая его вручную?


person Halvor Holsten Strand    schedule 21.06.2014    source источник


Ответы (3)


Прямо в документе для AsyncTask. Есть два. Их называют

AsyncTask.SERIAL_EXECUTOR

а также

AsyncTask.THREAD_POOL_EXECUTOR

соответственно.

Обратите внимание, что эти два исполнителя оба используют для выполнения один и тот же многопоточный вспомогательный исполнитель. Serial Executor не однопоточный! Перед ним просто стоит очередь, которая принудительно выполняет последовательное выполнение задач.

person G. Blake Meike    schedule 21.06.2014

Платформа Android AsyncTask имеет два исполнителя по умолчанию: SerialExecutor и ThreadPoolExecutor. AsynkTask использует другого исполнителя, так как исполнитель по умолчанию зависит от платформы.

Начиная с DONUT, это было изменено на пул потоков, позволяющий нескольким задачам работать параллельно. Начиная с HONEYCOMB, задачи снова выполняются в одном потоке, чтобы избежать распространенных ошибок приложений, вызванных параллельным выполнением.

Вы можете заставить выбрать исполнителя для выполнения задачи в исполнителях, которые вы хотите, используя этот функция Вы можете передать AsycTask.SERIAL_EXECUTOR или AsycTask.THREAD_POOL_EXECUTOR этой функции. И после этого вы можете использовать его для своих нужд.

person busylee    schedule 21.06.2014

Вы получаете RejectedExecutionException, потому что очередь ожидания пула потоков заполнена, и вы пытаетесь опубликовать другую задачу. Возможно, вам следует начать здесь, чтобы реорганизовать/переосмыслить свой код, потому что размер очереди, по-видимому, равен 10 плюс активный поток, которого должно быть достаточно в большинстве случаев. Очень вероятно, что некоторые из ваших задач не завершаются или выполняются долго и блокируют другие, или вы дико публикуете темы;)

Asynctask имеет 2 встроенных пула потоков:

В SDK > 11 SERIAL_EXECUTOR используется по умолчанию. Поэтому вы можете попробовать THREAD_POOL_EXECUTOR, но имейте в виду, что это можно использовать только в SDK => 11, потому что executeOnExecutor был более новым методом. Это решит вашу непосредственную проблему, но вам, возможно, следует пересмотреть, нужно ли вам столько потоков. Или используйте другие методы, например. services, если у вас много длительных задач.

В качестве альтернативы, если вам нужен собственный ThreadPool, вы можете создать его с помощью Executors: например. Executors.newCachedThreadPool( ) (среди других статических конструкторов).

person Patrick Favre    schedule 21.06.2014
comment
Обратите внимание, что SERIAL_EXECUTOR и THREAD_POOL_EXECUTOR используют один и тот же многопоточный исполнитель. Последовательный исполнитель просто имеет очередь перед ним, так что задачи выполняются последовательно. - person G. Blake Meike; 21.06.2014