SynchronousQueue VS TransferQueue

В Java 7 появился новый интерфейс TransferQueue в добавлении к уже существующему со времен Java 5 SynchronousQueue. Возникает резонный вопрос — для чего?

Для начала о TransferQueue

В Java 7 появился новый интерфейс TransferQueue и соответствующая реализация LinkedTransferQueue.

TransferQueue расширяет BlockingQueue, который в свою очередь расширяет Queue интерфейс, добавленный в Java 5. BlockingQueue — это очередь, которая может блокировать и потоки Поставщиков (Producer) при добавлении элементов в переполненную очередь, и потоки Потребителей (Consumer), при извлечении из пустой очереди. Основная задача блокирующих очередей — справляться с наплывом данных, которые система не в состоянии обработать за приемлемое время.

TransferQueue развивает эту идею и идет дальше, блокируя поток Поставщика до тех пор, пока элемент не будет извлечен потоком Потребителя. Ключевой метод — transfer() — блокировка происходит до тех пор, пока элемент не перейдет от одного потока к другому.

Существуют дополнительные методы — две формы передачи элементов tryTransfer() — либо блокирующая с таймаутом, либо неблокирующая, но осуществляющая передачу только при наличии ожидающего Потребителя. Так же существует пара вспомогательных методов hasWaitingConsumer() и getWaitingConsumerCount().

Пара слов о SynchronousQueue

Все мы помним о SynchronousQueue, который появился ранее в Java 5, предоставляет очередь размеров в 0 элементов и который так хорошо подходит для передачи элементов между потоками. Эта очередь работает по принципу «один вошел — один вышел». Каждая операция вставки блокирует поток Поставщика до тех пор, пока поток Потребителя не получит элемент из очереди и наоборот, Потребитель будет ждать пока Поставщик не вставит элемент в очередь.

SynchronousQueue более специализированный по сравнению с TransferQueue и это позволяет разработчику решать где использовать обычные блокирующие очереди, а где гарантированную передачу элементов.

SynchronousQueue vs TransferQueue

LinkedTransferQueue совмещает преимущества ConcurrentLinkedQueue, SynchronousQueue (в «справедливом» режиме) и неограниченный LinkedBlockingQueues.

Согласно авторам LinkedTransferQueue (William Scherer, Doug Lea, and Michael Scott Scalable Synchronous Queues тесты производительности показывают преимущество над существовавшими в Java 5 альтернативами. LinkedTransferQueue выигрывает у SynchronousQueue от 3 до 14 раз в зависимости от «справедливости» режимов (fair/unfair). Поскольку SynchronousQueue используется при передаче задач в ThreadPoolExecutor, то в результате можно ожидать улучшение производительности. Учитывая важность Executor в параллельном программировании, становится понятной важность добавления новой реализации.

SynchronousQueue использует две очереди — для ожидания поставщиков и потребителей — соответственно и защищает обе очереди одной блокировкой. LinkedTransferQueue использует CAS операции для реализации неблокирующих алгоритмов и позволяет избежать узкого горлышка.

На этом пока все. Если у вас есть вопросы или комментарии — буду рад их услышать. Присоединяйтесь к беседе! Если вам понравилась статья — делитесь с друзьями, подписывайтесь на блог.

Share with friends

Comments


Nuance of Java development

This blog is about Java development and describes in detail the most important topics.
Some part of blog is written in Russian.

Return back to list of posts

Subscribe to blog

Search on site