Простое объяснение пула потоков Android (1)

Каталог статей серии

Пул потоков Android в первой главе объясняется простым языком (1) Пул потоков Android во
второй главе объясняется простым языком (2)



Предисловие

При разработке Android трудоемкие задачи часто обрабатываются в потоках, не связанных с пользовательским интерфейсом. В настоящее время потоки необходимы для обработки асинхронных задач. Если поток создается каждый раз и уничтожается после выполнения, он будет использовать множество сцен, требующих частого использования нескольких потоков. Потеря ресурсов и производительности. А потоки легко делать независимо друг от друга, и их сложно контролировать.

Чтобы устранить недостатки использования потоков, в Java 1.5 предоставляется структура Executor, которая разделяет отправку и выполнение задач. Подача задач передается Runnable или Callable, а платформа Executor используется для обработки задач. Базовым классом реализации платформы Executor является ThreadPoolExecutor.


Во-первых, значение пула потоков

В программе много параллельных потоков. Если каждое ручное создание выполняется только в течение короткого времени и задача завершается, то частое создание и уничтожение потоков снизит эффективность системы и снизит эффективность использования ЦП. Для экономии ресурсов и повышения эффективности Java предоставляет пул потоков для решения проблемы.

Пул потоков на самом деле является контейнером, содержащим несколько потоков. Потоки можно использовать многократно, что устраняет необходимость в частом создании объектов потоков, и нет необходимости многократно создавать потоки и потреблять слишком много ресурсов.


Во-вторых, каковы преимущества пулов потоков

  1. Уменьшите потребление системных ресурсов и уменьшите потребление, вызванное созданием и разрушением потоков, за счет многократного повторного использования существующих потоков;
  2. Повышение скорости отклика системы. Когда задача поступает, ее можно выполнить немедленно, не дожидаясь создания нового потока, повторно используя существующие потоки;
  3. Повысьте управляемость потоков, отрегулируйте количество рабочих потоков в соответствии с пропускной способностью системы, чтобы предотвратить чрезмерное использование памяти OOM (каждый поток потребляет около 1 МБ). В то же время существует слишком много потоков, и частое переключение ЦП приведет к большим объемам Планирование временных затрат и сокращение времени фрагмента планирования ЦП. И вы можете использовать пул потоков для равномерного распределения, настройки и мониторинга потоков.
  4. Обеспечьте более мощные функции, пул потоков с задержкой времени.

Три, создание пула потоков

Интерфейс верхнего уровня пула потоков в Java - это java.util.concurrent.Executor, но в строгом смысле Executor - это не пул потоков, а инструмент для выполнения потоков. Настоящий интерфейс пула потоков java.util.concurrent.ExecutorService.

Сложнее настроить пул потоков. Если вы не совсем понимаете принцип пула потоков, вполне вероятно, что настроенный пул потоков не является оптимальным, поэтому он предоставляется в классе фабрики потоков java.util.concurrent.Executors Некоторые статические фабрики генерируют несколько часто используемых пулов потоков. Официальная рекомендация - использовать инженерный класс Executors для создания объектов пула потоков. Executors - это инструменты и фабричные классы для Executor, ExecutorService, ScheduledExecutorService, ThreadFactory и Callable.

Если ThreadPoolExecutor создан, Executors вызывает newFixedThreadPool, newSingleThreadExecutor и newCachedThreadPool для создания пулов потоков, которые относятся к типу ThreadPoolExecutor. Независимо от того, какой метод создания класса Executors вызывается, в конечном итоге будет вызван конструктор класса ThreadPoolExecutor.
код показан ниже:

/**
 *
 * @param corePoolSize 保留在池中的线​​程数,即使*处于空闲状态,
 *                     除非设置了{@code allowCoreThreadTimeOut}
 * @param maximumPoolSize 池中允许的最大线程数
 * @param keepAliveTime 当线程数大于核心时,这是多余的空闲线程在终止之前等待新任务的最长时间。
 * @param unit {@code keepAliveTime}参数的时间单位
 * @param workQueue 在执行任务之前用于保留任务的队列。该队列将仅保存由{@code execute}方法提交的{@code Runnable} *任务。
 * @param threadFactory 执行程序创建新线程时要使用的工厂
 * @param handler 当执行被阻塞时要使用的处理程序,因为达到了线程界限和队列容量,注意它并不是一个我们常见的Handler
 * @throws IllegalArgumentException 如果满足下列条件之一,则报IllegalArgumentException异常:
 *         {@code corePoolSize < 0}<br>
 *         {@code keepAliveTime < 0}<br>
 *         {@code maximumPoolSize <= 0}<br>
 *         {@code maximumPoolSize < corePoolSize}
 * @throws NullPointerException  如果 workQueue、threadFactory、handler之一为空,则报NullPointerException异常
 */
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {
    
    
}

В-четвертых, конструктор подробно

параметр Описание
corePoolSize Количество основных потоков. Когда количество потоков меньше этого значения, пул потоков будет отдавать приоритет созданию новых потоков для выполнения новых задач.
maximumPoolSize Максимальное количество потоков, которое может поддерживать пул потоков.
keepAliveTime Время жизни неактивных потоков
Ед. изм Параметр keepAliveTime - это единица времени выживания незанятого потока. Это перечисляемый класс.
workQueue Очередь задач, используемая для кеширования невыполненных задач
threadFactory Фабрика ниток. Более осмысленное имя может быть установлено для нового потока через фабрику
обработчик Стратегия отказа. Когда и пул потоков, и очередь задач переполнены, для обработки новых задач используется стратегия отклонения. По умолчанию используется AbortPolicy, то есть генерировать исключение напрямую.

1. Пул потоков corePoolSize по умолчанию пуст, и поток будет создан только при отправке
задачи. Если количество выполняемых в настоящее время потоков больше, чем corePoolSize, потоки создаются в зависимости от ситуации. Если вы вызываете метод prestartAllcoreThread пула потоков, пул потоков заранее создаст и запустит все основные потоки, чтобы дождаться выполнения задач.

2. maximumPoolSize
Если очередь задач заполнена, а количество потоков меньше, чем maximumPoolSize, пул потоков все равно будет создавать новые потоки для обработки задач.

3. keepAliveTime
Когда количество потоков больше, чем у ядра, это наибольшее время, в течение которого избыточные простаивающие потоки ждут новых задач перед завершением, и по истечении этого времени они будут повторно использованы.

Если задач много, и время выполнения каждой задачи невелико, вы можете увеличить keepAliveTime, чтобы улучшить использование потока. Кроме того, если для свойства allowCoreThreadTimeOut установлено значение true, keepAliveTime также будет применяться к основному потоку.

4. Единица времени параметра TimeUnit
keepAliveTime. Необязательными единицами измерения являются дни, часы, минуты, секунды, миллисекунды и т. Д.

5. workQueue
используется для хранения очереди задач перед выполнением задач. В этой очереди будут сохраняться только выполняемые задачи, отправленные методом execute. Очередь задач имеет тип BlockingQueue, который является блокирующей очередью.

6. ThreadFactory
может использовать фабрику потоков, чтобы задать имя для каждого созданного потока. В обычных условиях этот параметр настраивать не нужно.

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

Параметры построения ThreadPoolExecutor должны соответствовать определенным условиям:

  1. Если возникает одна из следующих ситуаций, во время сборки будет выброшено исключение IllegalArgumentException:
    1. corePoolSize <0
    2. keepAliveTime <0
    3. maximumPoolSize <= 0
    4. maximumPoolSize <corePoolSize
  2. Если произойдет одна из следующих ситуаций, во время процесса построения будет выброшено исключение NullPointerException:
    1. workQueue имеет значение null
    2. threadFactory имеет значение null
    3. обработчик имеет значение null

Пять, общий ThreadPoolExecutor

Различные типы ThreadPoolExecutor могут быть созданы путем прямой или косвенной настройки параметров ThreadPoolExecutor. Среди них обычно используются 4 типа пулов потоков: FixedThreadPool, CachedThreadPool, SingleThreadExecutor, ScheduledTheadPool.

1. FixedThreadPool


2. CachedThreadPool


3. SingleThreadExecutor


4. ScheduledTheadPool


подводить итоги

Для получения дополнительных знаний, таких как стратегия создания потоков, стратегия повторного использования ресурсов потоков, стратегия очередей потоков, стратегия отклонения потоков и т. Д. В пуле потоков , прочтите мой другой пост в блоге о пуле потоков Android простым способом (2)

рекомендация

отblog.csdn.net/luo_boke/article/details/107580536