Блокировка очередей на Java
1. Что такое блокирующая очередь?
Блокирующая очередь (Blockqueue) - это очередь, которая поддерживает две дополнительные операции. Эти две дополнительные операции:
Когда очередь пуст, поток, который приносит элемент, будет ждать, пока очередь станет непустыми.
Когда очередь будет заполнена, поток, который хранит элементы, будет ждать, пока будет доступна очередь.
Блокирующие очереди часто используются в сценариях производителей и потребителей. Производители - это потоки, которые добавляют элементы в очереди, а потребители - это потоки, которые берут элементы из очередей. Блокирующая очередь - это контейнер, где производитель хранит элементы, а потребитель получает только элементы из контейнера.
2. Блокировка очереди на Java
Семь очередей блокировки приведены в JDK:
ArrayBlockingQueue
Arrayblockingqueue - это ограниченная очередь блокировки, реализованная с использованием массивов. Эта очередь сортирует элементы в соответствии с принципом первого в первом (FIFO). По умолчанию посетители не гарантируются получить доступ справедливо. Так называемая довольно доступная очередь относится ко всем заблокированным потокам производителей или потребительским потокам. Когда очередь доступна, очередь можно получить в порядке блокировки. То есть поток производителя, который сначала блокирует элементы в очередь сначала, а потребительский поток, который сначала блокирует, может сначала получить элементы из очереди. Обычно пропускная способность снижается, чтобы обеспечить справедливость . Мы можем создать справедливую очередь блокировки, используя следующий код:
ArrayBlockqueue Fairqueue = new ArrayBlockingQueue (1000, True);
Справедливость его доступа достигается за счет блокировки повторного блока.
LinkedBlockingqueue
LinkedBlockingQueue - это ограниченная очередь блокировки, реализованная с помощью связанных списков. По умолчанию и максимальная длина этой очереди - integer.max_value. Эта очередь сортирует элементы в соответствии с принципом первого в первую очередь.
Приоритет блокировки
Приоритет Blockingqueue - это неограниченная очередь, которая поддерживает приоритет. По умолчанию элементы расположены в естественном порядке, а правила упорядочения элементов также могут быть указаны через компаратор компаратора. Элементы расположены в порядке возрастания.
Задержка
DolectQueue - это неограниченная очередь блокировки, которая поддерживает задержку сбора элементов. Очередь реализована с использованием приоритета. Элементы в очереди должны реализовать задержку интерфейса, а при создании элемента вы можете указать, сколько времени требуется, чтобы получить текущий элемент из очереди. Элементы могут быть извлечены из очереди только после истечения срока задержки. Мы можем использовать задержку в следующих сценариях приложения:
Проектирование системы кеша: DelayQueue может использоваться для сохранения периода достоверности элементов кеша, а поток может использоваться для запроса DolectQueue. Как только элемент может быть получен из задержки, это означает, что период достоверности кэша достиг.
Запланированный график задач. Используйте DelockQueue, чтобы сохранить задачи и время выполнения, которые будут выполнены в день. Как только задача будет получена из задержки, она начнет выполнять. Например, TimerQueue реализована с использованием DolectQueue.
Как реализовать задерживаемый интерфейс
Мы можем обратиться к классу запланированного количества в PradeLedThreadPoolexeCutor. Этот класс реализует отсроченный интерфейс. Во -первых: при создании объекта используйте время для записи, когда объект можно использовать перед записи. Код заключается в следующем:
Graduledfuturetask (runnable r, v -результат, длинный NS, длительный период) {super (r, result); this.Time = ns; this.period = период; this.ewenceNumber = sequencer.getAndIncrement ();}Затем используйте GetDelay, чтобы запросить, как долго текущий элемент должен быть отложен. Код заключается в следующем:
Public Long GetDelay (UNIT UNIT) {return Unit.convert (time - now (), timeUnit.nanoseconds); }Через конструктор мы видим, что единица параметра времени задержки NS - наносекунд. Лучше всего использовать наносекунд при его проектировании самостоятельно, потому что вы можете указать любую единицу при получении. После того, как наносекунд используются в качестве устройства, а время задержки меньше, чем наносекунд, это будет проблемным. При использовании обратите внимание, что когда время будет меньше, чем текущее время, GetDelay вернет отрицательное число.
Наконец, мы можем использовать время для указания порядка в очереди, например: пусть самое длительное время задержки будет размещено в конце очереди.
public int compareto (задержка других) {if (Другое == это) return 0; if (другой экземпляр glededfuturetask) {waredudfuturetask x = (pressuledfuturetask) другие; Long Diff = время - X.Time; if (diff <0) return -1; иначе if (diff> 0) return 1; иначе if (sequenceNumber <x. sechenceNumber) return -1; иначе возврат 1; } long d = (getDelay (timeUnit.nanoseconds) -other.getDelay (TimeUnit.nanoseconds)); возврат (d == 0)? 0: ((D <0)? -1: 1); }Как реализовать отсроченные очереди блокировки
Реализация очередей блокировки задержки очень проста. Когда потребитель получает элементы из очереди, если элемент не достигает времени задержки, он блокирует текущий поток.
длинная задержка = First.getDelay (TimeUtil.nanoseconds); if (задержка <= 0) {return q.poll; // Блокировка очереди} else if (leader! = null) {// head представляет собой поток, ожидающий сообщения из Queue Blocking Queue.await (); // Пусть поток введите сигнал ожидания} else {// Когда лидер является нулевым, установите текущий поток на лидер, который читает thishread = thread.currentThread (); try {Leader = thisThread; // Использовать метод waitnanos (), чтобы сделать текущий поток ждать полученного сигнала или ожидания времени задержки. }}}Synchronousqueue
Synchronousqueue - это блокирующая очередь, которая не хранит элементы. Каждая операция пута должна ждать операции, в противном случае элементы не могут быть добавлены. Synchronousqueue можно рассматривать как прохожие, ответственный за передачу данных, обработанных потоком производителя непосредственно в поток потребителя. Сама очередь не хранит никаких элементов, что очень подходит для переходных сценариев. Например, данные, используемые в одном потоке, передаются в другой поток для использования. Пропускная способность SynchronousQueue выше, чем у
LinkedBlockingQueue и ArrayBlockingQueue.
Он поддерживает очереди справедливого доступа. По умолчанию это все еще несправедливый механизм политики
LinkedTransferqueue
LinkedTransferqueue - это неограниченная блокирующая очередь Transferqueue, состоящая из связанной структуры списка. По сравнению с другими блокирующими очередями, LinkedTransferqueue имеет больше методов Trytransfer и переноса.
метод передачи
Если потребитель в настоящее время ожидает получения элемента (когда потребитель использует метод take () или метод ограниченного времени опроса ()), метод передачи может немедленно перенести элементы, передаваемые производителем потребителю. Если ни один потребитель не ждет приемного элемента, метод передачи хранит элемент в хвостовом узле очереди и ожидает, пока потребитель не будет употреблять элемент до возвращения.
метод Trytransfer
Он используется для проверки того, могут ли элементы, представленные производителем, быть непосредственно передаваться потребителю. Если ни один потребитель не ждет приемного элемента, False возвращается. Разница между методом передачи заключается в том, что метод Trytransfer возвращает немедленно независимо от того, получает ли потребитель его или нет. Метод передачи должен ждать, пока потребитель не поглотит его перед возвращением.
Для метода Trytransfer (E E, длительный тайм -аут, временный единица) с ограничением времени он пытается передать элемент, переданный производителем непосредственно потребителю, но если потребитель не потребляет элемент, он будет ждать указанное время до возвращения. Если тайм -аут не использовал элемент, он вернет ложь, и если элемент потребляется в течение времени ожидания, он вернет true.
LinkedBlockingDeque
LinkedBlockingDeque - это двунаправленная очередь блокировки, состоящая из связанной структуры списка. Так называемая двусторонняя очередь относится к тому факту, что вы можете вставить и удалять элементы с обоих концов очереди. Поскольку двойная очередь имеет дополнительную запись в очередь операции, конкуренция уменьшается вдвое, когда несколько потоков соединяются в очередь одновременно. По сравнению с другими блокирующими очередями, LinkedBlockingDeque имеет больше AddFirst, Addlast, Surfersfirst, Surferlast, Peekfirst, Peeklast и других методов. Метод заканчивается первым словом, указывает внедрение, получение или удаление первого элемента двойной очереди. Метод, заканчивающий последним словом, указывающим, что последний элемент двойной очереди вставлен, получен или удалена. Кроме того, метод вставки добавлена эквивалентен добавлению, а метод удаления эквивалентен удалению первого. Тем не менее, метод принятия эквивалентен привлечению. Я не знаю, является ли это ошибкой в JDK, и более четко использовать метод с первым и последним суффиксом при его использовании. Емкость очереди может быть инициализирована при инициализации LinkedBlockingDeque, чтобы предотвратить его отек, когда она переоценка. Кроме того, в режиме «кражи» можно использовать двунаправленную очередь блокировки.
Спасибо за чтение, я надеюсь, что это поможет вам. Спасибо за поддержку этого сайта!