задний план
Шаблон Thread-Per-Message — это способ назначения потока для каждой команды или запроса, и этот поток выполняет работу. Так и будет委托消息的一端
а также执行消息的一端
Реализован двумя разными потоками. Режим потока в основном состоит из трех частей:
- Участник запроса (принципал), то есть отправитель сообщения или запросчик команды
- Участник Host, который принимает запросы на сообщения, отвечает за назначение рабочего потока для каждого сообщения.
- Участник Worker, поток, выполняющий задачу участника Request, запускается участником Host.
Потому что после вызова метода вы должны дождаться полного выполнения метода, прежде чем продолжить выполнение следующей операции.После использования потока вы можете сразу вернуться к следующей операции, не дожидаясь выполнения конкретной задачи.
Поскольку для каждого запроса в паттерне Thread-Per-Message Pattern генерируется и запускается поток, а запуск потока — трудоемкая работа, ввиду этого Worker Thread предлагается повторно использовать уже запущенный поток.
Определение режима пула потоков
Рабочий поток обычно называют пулом потоков. Этот режим заранее запускает определенное количество рабочих потоков. Когда работа не запрашивается, все рабочие потоки будут ждать новых запросов. После поступления работы поток будет пробужден из пула потоков для выполнения задачи. После завершения выполнения он будет продолжать ждать в пуле потоков для выполнения задачи. работа пула задач поступление заявки.
- Пул задач: он в основном хранит коллекцию принятых запросов. Его можно использовать для буферизации полученных запросов. Размер можно установить, чтобы указать максимальное количество запросов, которые могут быть приняты одновременно. К этому пулу задач в основном обращается пул потоков.
- Пул потоков: это набор рабочих потоков, размер которых может обеспечивать параллельную обработку рабочих нагрузок. Для размера пула потоков можно заранее сгенерировать определенное количество потоков, а количество потоков можно динамически увеличивать или уменьшать в зависимости от реальной ситуации. Размер пула потоков не максимально велик, и переключение потоков тоже займет время.
Роли в шаблоне пула потоков
Структура данных пула хранения может быть либо массивом, либо коллекцией.Vector обычно используется в классе коллекции, который является потокобезопасным.
Роль рабочего потока:
- Участник клиента, участник, отправивший Запрос
- Участник канала, отвечающий за кеширование запросов запросов, инициализацию потоков запуска и назначение рабочих потоков.
- Рабочий участник, рабочий поток, который специально выполняет запрос.
- Запросить участника
Способ ожидания непустого пула задач внутри рабочего потока называется ожиданием вперед.
Способ, которым поток канала предоставляет рабочему потоку возможность определить, что пул задач не пуст, называется обратным ожиданием.
Пример приложения
Используя синхронизированные блоки для обработки, контейнер Vector хранит клиентские запросы. Используя Vector для хранения, это по-прежнему последняя позиция каждой коллекции для добавления запроса и удаления запроса из начальной позиции для обработки. В Channel есть методы запроса кэша и методы запроса обработки, режимы генератора и потребителя используются для обработки запросов к хранилищу, а ожидание вперед используется для определения непустого состояния пула задач.
Этот тип экземпляра может быть заимствован из режима обработки пользовательских запросов сети ServerSocket, который имеет хорошую расширяемость и практичность.
Участники канала
public class Channel {
public final static int THREAD_COUNT=4;
public static void main(String[] args) {
//注意:Map不是Collection的子类,都是java.util.*下的同级包
Vector pool=new Vector();
//工作线程,初始分配一定限额的数目
WorkerThread[] workers=new WorkerThread[THREAD_COUNT];
//初始化启动工作线程
for(int i = 0; i < workers.length; i++)
{
workers[i] = new WorkerThread(pool);
workers[i].start();
}
//接受新的任务,并且将其存储在Vector中
Object task = new Object();//模拟的任务实体类
//此处省略具体工作
//在网络编程中,这里就是利用ServerSocket来利用ServerSocket.accept接受一个Socket从而唤醒线程
//当有具体的请求达到
synchronized(pool)
{
pool.add(pool.size(), task);
pool.notifyAll();//通知所有在pool wait set中等待的线程,唤醒一个线程进行处理
}
//注意上面这步骤添加任务池请求,以及通知线程,都可以放在工作线程内部实现
//只需要定义该方法为static,在方法体用同步块,且共享的线程池也是static即可
//下面这步,可以有可以没有根据实际情况
//取消等待的线程
for(int i = 0; i < workers.length; i++)
{
workers[i].interrupt();
}
}
}
Основная функция этого заключается в следующем
- Буферизация потоков клиентских запросов (с использованием шаблонов производителя и потребителя)
- Поток, в котором хранятся запросы клиентов
- Initialize запускает определенное количество потоков
- Активно активировать некоторые потоки в наборе ожидания в пуле задач для выполнения задач.
Определите два набора: один предназначен для хранения клиентских запросов с использованием вектора, а другой — для хранения потоков, т. е. количества потоков в пуле потоков.
Vector является потокобезопасным, он реализует Collection и List и может реализовывать расширяемые массивы объектов.
Как и массив, он содержит компоненты, доступ к которым можно получить с помощью целочисленных индексов. Однако размер вектора может быть увеличен или уменьшен по мере необходимости для добавления или удаления элементов после создания вектора.
Коллекция в основном включает коллекции, связанные со списками, коллекции, связанные с наборами, и коллекции, связанные с очередями.
рабочий поток
public class WorkerThread extends Thread {
private List pool;//任务请求池
private static int fileCompressed = 0;//所有实例共享的
public WorkerThread(List pool)
{
this.pool = pool;
}
//利用静态synchronized来作为整个synchronized类方法,仅能同时一个操作该类的这个方法
private static synchronized void incrementFilesCompressed()
{
fileCompressed++;
}
public void run()
{
while(true)
{
synchronized(pool)
{
//利用多线程设计模式中的
//Guarded Suspension Pattern,警戒条件为pool不为空,否则无限的等待中
while(pool.isEmpty())
{
try{
pool.wait();//进入pool的wait set中等待着,释放了pool的锁
}catch(InterruptedException e)
{
}
}
pool.remove(0);//获取任务池中的任务,并且要进行转换
}
//下面是线程所要处理的具体工作
}
}
}
Доступ к переменной пула осуществляется через общий мьютекс, что гарантирует бесконечный цикл ожидания. Когда поток пробуждается, ему необходимо повторно получить блокировку пула и выполнить ее снова.synchronized
Остальная работа в кодовом блоке, когда он не пустой, продолжайте судить, пустой ли он, если нет, выпрыгивайте из цикла. Задача должна быть удалена из пула задач для выполнения, единообразно используется для добавления с конца и удаления с начала
Суммировать
Режим пула потоков широко используется в реальном программировании, например, пул соединений с базой данных, соединение с длинным сокетом и т. д. Определенное количество рабочих потоков используется для выполнения задач, которые постоянно отправляются, экономя ограниченные и дорогостоящие ресурсы потоков. Этот режим имеет следующие преимущества:
- Компенсируйте накладные расходы на создание потоков и улучшите время отклика
- Инкапсулирует управление жизненным циклом рабочего потока
- Уменьшите накладные расходы на уничтожение потоков
Но чтобы правильно использовать режим пула потоков, вам также необходимо учитывать следующие проблемы:
- Выбор рабочей очереди: Обычно существует три метода очереди: Ограниченная очередь Сама рабочая очередь не ограничивает количество задач, ожидающих выполнения в пуле потоков, но фактические задачи, которые могут быть размещены в рабочей очереди, зависят от использования ресурсы самой задачей Ситуация; рабочая очередь UnboundQueue (UnboundQueue) ограничивает количество больших людей, ожидающих в пуле потоков, что может в определенной степени ограничивать потребление ресурсов; SymchrinousQueue (SymchrinousQueue) не применяется при отправке задач в буфер Блокирующий метод входа в очередь, поэтому очереди ожидания нет, и новый поток будет обрабатывать задачу, не попавшую в очередь.
- Параметры настройки размера пула потоков: слишком большой тратит ресурсы впустую, слишком большой не может полностью использовать ресурсы, поэтому размер пула потоков зависит от характеристик задач, которые должны обрабатываться пулом потоков, системных ресурсов и дефицитных ресурсов, используемых блокировки задач.
- Мониторинг пула потоков: размер пула потоков, емкость рабочей очереди и ограничение времени простоя потоков. Эти знакомые процессы отладки должны отслеживаться программами для облегчения отладки. Класс ThreadPoolExecutor предоставляет методы мониторинга.
- Утечка потока: рабочие потоки в пуле потоков неожиданно завершатся, что уменьшит количество рабочих потоков, фактически доступных в пуле потоков. Причина в том, что обработка исключений метода запуска объекта потока не захватывает RuntimeException и Error, что приводит к неожиданному возврату метода запуска, что приводит к неожиданному завершению соответствующего потока. Поэтому вам нужно внедрить и поймать соответствующее исключение. Но есть еще одна возможность, о которой следует помнить: если потоку необходимо запросить внешние ресурсы, а для запроса внешних ресурсов нет ограничения по времени, поток действительно может протечь.
- Надежность и стратегия обработки насыщения пула потоков. Выбор рабочих очередей не позволяет обрабатывать изменения в требованиях к размеру потоков, поэтому требуется стратегия обработки насыщения потоков.
- Тупик: потоки, запрашивающие аналогичные ресурсы, могут зайти в тупик.
- Очистка простаивающих потоков пула потоков: потоки, которые не обрабатывают задачи в течение длительного времени, являются пустой тратой системных ресурсов, поэтому требуются соответствующие коды обработки.
Ссылаться на
Основная ссылка этой статьи, вы можете нажать, чтобы прочитать исходный текст: