Почему у THREAD_POOL_EXECUTOR AsyncTask есть предел очереди, а у SERIAL_EXECUTOR нет? - PullRequest
0 голосов
/ 24 января 2019

Мне любопытно, есть ли у кого-нибудь понимание того, почему платформа Android AsyncTask, встроенная в Executor, не имеет предела или не является неограниченной по количеству в очереди AsyncTask s они могут справиться.

THREAD_POOL_EXECUTOR изначально имел ограничение на LinkedBlockingQueue 10 в ранних версиях Android. Начиная с KitKat , он имеет ограничение 128.

1014 * ArrayDeque не имеет , никогда не имело предела , так как оно было введено в Honeycomb по умолчанию AsyncTask Executor.

ArrayDeque API не позволяет ограничить его емкость. Но конструктор LinkedBlockingQueue по умолчанию *1025* обеспечит ограничение емкости очереди по умолчанию Integer.MAX_VALUE (2 147 483 647), по существу неограниченное.

Во всяком случае, SERIAL_EXECUTOR с большей вероятностью получит резервные копии с Runnable AsyncTask с, поскольку они не могут выполняться параллельно. Но оба одинаково способны исчерпать память, если слишком много задач поставлено в очередь, прежде чем они могут быть выполнены. THREAD_POOL_EXECUTOR гораздо быстрее достигает своего предела, выбрасывая RejectedExecutionException, когда его очередь превышает предел 128, тогда как SERIAL_EXECUTOR будет по-прежнему иметь возможность добавлять задачи, пока не закончится память.

У меня есть сценарий использования, когда мне нужно быстро поставить в очередь несколько сотен задач рендеринга, которые должны выполняться асинхронно. Использование AsyncTask по умолчанию SERIAL_EXECUTOR работает просто отлично. Но эти задачи рендеринга могут и в идеале должны выполняться параллельно, поскольку они не имеют общего состояния. Если я изменю код для использования AsyncTask THREAD_POOL_EXECUTOR, приложение вылетит с: java.util.concurrent.RejectedExecutionException: Task android.os.AsyncTask$3@b4d342c rejected from java.util.concurrent.ThreadPoolExecutor@bcccef5[Running, pool size = 9, active threads = 9, queued tasks = 128, completed tasks = 53].

Есть ли причина, по которой я не хотел бы создавать свой собственный Executor, отражающий THREAD_POOL_EXECUTOR, кроме как без ограничения емкости очереди?

...