Неустойчиво и синхронизировано в AsyncTask

Во внутренней реализации AsyncTask (в Android SDK) здесь sDefaultExecutor объявляется с ключевым словом volatile а метод execute() в SerialExecutor объявляется с synchonized ключевым словом.

  1. Теперь, поскольку AsyncTask может быть выполнен только из потока пользовательского интерфейса, а также, если мы выполняем экземпляр AsyncTask , мы не можем повторно запустить тот же экземпляр, если предыдущий экземпляр не завершил выполнение. Итак, как же там могут быть случаи с несколькими потоками?
  2. Почему у SerialExecutor есть ArrayDeque ? Потому что в то же время у нас может быть только одна задача. Если мы создадим новый экземпляр AsyncTask , тогда не получим новый экземпляр ArrayDeque , который снова имеет только одну задачу.
  3. То же самое происходит с ThreadPoolExecutor . Почему пулы потоков необходимы, если для конкретного экземпляра AsyncTask у нас может быть только одна задача? Для этого достаточно одного потока.

Мы не можем повторить тот же экземпляр, если предыдущий экземпляр не завершил выполнение. Итак, как же там могут быть случаи с несколькими потоками?

Например, есть основной поток пользовательского интерфейса и потоки исполнителей.

Почему у SerialExecutor есть ArrayDeque? Потому что в то же время у нас может быть только одна задача. Если мы создадим новый экземпляр AsyncTask, тогда не получим новый экземпляр ArrayDeque, который снова имеет только одну задачу.

Неправда, что может быть только одна задача. Серийный исполнитель может выполнять только одну задачу за раз, но вы можете ставить в очередь несколько задач в основном потоке, и они выполняются один за другим в потоке исполнителей.

Существуют и другие исполнители, чем исполнители серийных номеров, также как и исполнитель пула потоков, о котором вы расскажете позже.

То же самое происходит с ThreadPoolExecutor. Почему пулы потоков необходимы, если для конкретного экземпляра AsyncTask у нас может быть только одна задача? Для этого достаточно одного потока.

Ваша предпосылка только одной задачи одновременно неверна. Исполнитель пула потоков полезен для одновременного запуска нескольких задач async в отдельных потоках.

Как выглядит очередность таков и множество задач? Предположим, что я делаю экземпляр AsyncTask и выполняю его 5 раз. Затем, если вы работаете, другие 4 не запускаются. Как я могу получить несколько задач в любом случае?

Один экземпляр AsyncTask можно выполнить только один раз. Но вы можете публиковать несколько различных экземпляров AsyncTask для выполнения. Обратите внимание, что такая операция проводки ( execute() и т. Д.) Является асинхронной и возвращается до завершения задачи async, и вы можете запускать дополнительный код в потоке пользовательского интерфейса, включая отправку новых задач async для выполнения.

Для параллельного выполнения просто используйте executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ...) .

Верно ли также, что поскольку SerialExecutor является статическим, так что только один экземпляр его будет использоваться во всех экземплярах AsyncTask и, следовательно, требуется очередь?

Да, в приложении есть только один последовательный исполнитель, и он распределяется между всеми асинхронными задачами.