Предисловие
В многопоточном программировании нереально назначать поток каждой задаче, а накладные расходы и потребление ресурсов создания потока очень высоки. Пул ниток появился и стал для нас мощным инструментом для управления потоками. Через интерфейс исполнителя Java предоставляет стандартный метод для отделения процесса подачи задачи и процесса выполнения и использует выполнение для представления задачи.
Далее, давайте проанализируем реализацию платформы бассейна потоков Java ThreadPoolexeCutor.
Следующий анализ основан на JDK1.7
жизненный цикл
В ThreadPoolexeCutor верхние 3 бита емкости используются для представления состояния бега, которые являются:
1. Заключение: Получить новые задачи и задачи процесса в очереди задачи
2.shutdown: Задачи, которые не получают новые задачи, а обрабатывают очереди задачи
3.stop: никаких новых задач не получено, очередь задач не выпущена, и все выполняемые задачи прерваны одновременно
4. Удаление: все задачи были прекращены, количество потоков работников равно 0. Когда это состояние будет достигнуто, будет выполнено прекращение () будет выполнено.
5.tramined: завершен () был выполнен
Схема перехода состояния
Атомные классы используются для представления битов состояния в ThreadPoolexeCutor
Частный финальный atomicinteger ctl = new atomicinteger (ctlof (running, 0));
Модель пула потоков
Основные параметры
CorePoolSize: минимальное количество потоков живых работников (если установлено alludCoreThreadTimeOut, это значение равно 0)
Maximumpoolsize: максимальное количество потоков, ограниченное емкостью
KeepAliveTime: время выживания соответствующего потока, единица времени определяется TimeUnit
Workqueue: Рабочая очередь, хранение задач, которые должны быть выполнены
RejectExecutionHandler: Dize Policy, максимальная емкость пула потоков будет запускаться после полного пула потоков: первые три бита в емкости используются в качестве битов флага, то есть максимальная емкость рабочего потока (2^29) -1
Четыре модели
CachedThreadpool: бассейн кэш -нить. Если текущий размер пула потоков превышает требования к обработке, поток холостого хода будет переработан. Когда спрос увеличивается, могут быть добавлены новые потоки. Нет ограничений на размер пула потоков.
Fixedthreadpool: пул потоков фиксированного размера. При отправке задачи создается поток до тех пор, пока не будет достигнуто максимальное количество пулов потоков. В настоящее время размер пула потоков больше не будет изменяться.
SingleThreadPool: однопоточный пул потоков, в котором есть только один рабочий поток для выполнения задач. Это может гарантировать, что задачи выполняются последовательно в том порядке, в котором они находятся в очереди. Если этот поток заканчивается ненормально, будет создан новый поток для выполнения задач.
ПЕРЕДАЧА ПЕРЕДАЧА: Пул потоков с фиксированным размером и выполняет задачи задержанным или временным образом, аналогично таймеру.
Выполнить выполнение задачи
Основная логика:
1. Текущее количество потоков <corepoolsize, непосредственно откройте новый поток Core, чтобы выполнить AddWorker Task (команда, true)
2. Текущее количество потоков> = corepoolsize, и задача успешно добавлена в очередь работы
1). Проверьте, работает ли текущее состояние пула потоков
2). Если нет, задача отклоняется
3). Если это так, определите, является ли текущее количество потоков 0. Если это 0, добавьте поток работника.
3. Включите нормальное задание выполнения потока (команда, false) и отказаться от задачи, если она не запустит. Из приведенного выше анализа мы можем обобщить четыре этапа работы пула потоков:
1). Будет создан новый поток для обработки представленных задач.
2) .poolsize == corepoolsize. В настоящее время представленная задача входит в очередь работы. Рабочий поток получает выполнение задачи из очереди. В настоящее время очередь не пуста и не полна.
3). Также будет создан новый поток для обработки представленной задачи, но PoolSize <maxPoolsize
4) .poolsize == maxpoolsize и очередь полна, политика отказа будет запустить
Политика отклонения <br /> мы упоминали ранее, что если задача не может быть выполнена, она будет отклонена. DecuceedExecutionHandler - это интерфейс для обработки отклоненных задач. Вот четыре стратегии отклонения.
Abrortpolicy: политика по умолчанию, завершение задачи, брось DecuceedException
Callerrunspolicicy: выполнить текущую задачу в потоке вызывающего абонента, не бросая исключения
Отбросьтеполици: отбросьте политику, напрямую отбросьте задачу и не бросайте исключения
DI Scandolderspolicy: отказаться от самой старой задачи, выполнить текущую задачу и не бросить исключения
Рабочий в пуле потоков
Работник наследует AbstractqueudSynchronizer и Runnable. Первый предоставляет работнику функцию блокировки, а последний выполняет основной метод пробега работника рабочих потоков (работник W) (выполнение задачи SNAP из очереди задачи). Ссылки на работников встречаются в коллекции рабочих и защищены Mainlock.
Частный финальный reentrantlock mainlock = new Reentrantlock ();
Частный финальный хэшсет <Работник> рабочие = новый хэшсет <Работник> ();
Основная функциональная работоспособность
Ниже приведен упрощенная логика, примечание: выполнение каждого потока работника выполняет следующие функции
Final void Runworker (рабочий w) {Thread wt = Thread.currentThread (); Запустить задание = w.firsttask; w.firsttask = null; while (task! = null || (task = getTask ())! = null) {w.lock (); передэксек (wt, задача); task.run (); после эксплуатации (задача, брошенная); w.unlock (); } ProcessWorkErexit (w, завершенное обширное);} 1. Получите задачу от GetTask ()
2. Заблокируйте работника
3. Execute the Execute (WT, Task), который является методом расширения, предоставленным ThreadPoolexeCutor для подклассов
4. Запустите задачу. Если работник настроил первую задачу, первая задача будет выполнена первой и только один раз.
5. Выполнить послеэкскутату (задача, брошенная);
6. разблокировать работника
7. Если полученная задача является нулевой, закройте работника
Получите задачу получить
Очередь задач внутри бассейна резьбов представляет собой очередь блокировки, которая передается во время строительства.
Частный финальный блокировка <runnable> workqueue;
getTask () получает задачу из очереди задач, поддерживает блокировку и тайм -аут ожидания задач. Четыре ситуации приведут к возвращению NULL, а работник закрыт.
1. Количество существующих потоков превышает максимальное количество потоков
2. Пул потоков находится в состоянии остановки
3. Пул потоков находится в состоянии выключения, а очередь работы пуста
4. Тайм -аут задачи ожидания потока, а количество потоков превышает количество оставшихся потоков
Основная логика: время, заблокированная или блокирующая задачу ожидания в очереди блокировки. Занятая задача ожидания приведет к закрытию рабочей потока.
Timeed = AllowCoreThreadTimeOut || wc> corepoolsize; Runnable r = время? Workqueue.poll (KeepAliveTime, TimeUnit.nanoseconds): Workqueue.take ();
В ожидании задачи пройдет время в двух случаях:
1. Позвольте основным потокам ждать тайм -аута, то есть AllingCoreThreadTimeOut (TRUE)
2. Текущий поток - это обычный поток, в настоящее время WC> CorePoolsize
Очередь работы использует BlockingQueue, поэтому я не буду расширять ее здесь. Я напишу подробный анализ позже.
Суммировать
ThreadPoolexeCutor основан на модели производителя-потребителя. Операция задач отправки эквивалентна производителю, а поток выполнения задач эквивалентен потребителю.
Исполнители предоставляют четыре метода для построения модели пула потоков на основе ThreadPoolexecutor. Кроме того, мы можем непосредственно наследовать ThreadPoolexecutor и переписать методы перед эксплуатацией и последующей эксплуатации для настройки процесса выполнения задачи пула потоков.
Использование ограниченных очередей или неограниченных очередей необходимо учитывать в соответствии с конкретной ситуацией, и размер очереди работы и количество потоков также необходимо тщательно рассмотреть.
Политика отклонения рекомендуется использовать Callerrunspolicy, которая не отказывается от задачи и не бросает исключение, но вместо этого откидывает задачу в поток вызывающего абонента для выполнения.
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.