SynchronousQueue Vs Exchanger - PullRequest
       1

SynchronousQueue Vs Exchanger

14 голосов
/ 16 марта 2012

В чем разница между Exchanger и SynchronousQueue? И сценарии, в которых каждый из них может быть использован? Какой из них лучше по производительности? (Мудрый замок?)

Ответы [ 2 ]

10 голосов
/ 16 марта 2012

Exchanger - это более чистый механизм синхронизации, в то время как SynchronousQueue дополнительно предлагает все операции стандартной структуры данных очереди.Это означает, что вы можете, например, проверить, какие объекты находятся в очереди, отменить запланированные, но еще не выполненные действия, асинхронно удаляя элементы из очереди и т. Д. - операции, которые Exchanger не предлагает.Поскольку многие реализации позволяют устанавливать ограничение на размер очереди, вы получаете дополнительный контроль над использованием ресурсов и можете отбрасывать запросы, если очередь растет выше определенного порога.С другой стороны, Exchanger предлагает двустороннюю связь "из коробки", в то время как одна очередь - только один путь (хотя можно реализовать связь в другом направлении вручную).Поскольку во многих практических ситуациях требуются только отношения между производителями и потребителями, очередь часто лучше из-за более простого понимания API и перечисленных выше дополнительных операций.

В этой статье описывается практический пример использованияExchanger.Они концентрируются на том, чтобы избежать создания и сбора мусора новых объектов при обмене данными между потоками (в зависимости от реализации, очереди могут выделять записи, когда вы что-то добавляете к ним).Производительность, вероятно, будет зависеть от вашего конкретного случая использования.В примере они используют Exchanger для эффективности (избегая сбора мусора), но в большинстве случаев (если вам не нужно предоставлять задержки в миллисекундах), выделение объекта или двух не такая большая проблема, и я быпредпочитаю использовать очередь для дополнительного элемента управления, который позволяет.

РЕДАКТИРОВАТЬ: Я проверил источник для Exchanger.java в Oracle JDK, и он создает временные объекты класса Exchanger.Node в Exchanger.doExchange().Таким образом, кажется, что вопреки тому, что утверждают авторы связанной статьи, Exchanger не является свободным от выделения.Ни один не (довольно очевидно) LinkedBlockingQueue.ArrayBlockingQueue, напротив, не выделяет никаких временных объектов при добавлении к нему элемента.Он только выделяет массив для хранения максимально допустимого количества элементов при его создании, но это всего лишь одноразовая операция.Во время использования он не создает новые объекты, поэтому с точки зрения чистого GC он должен быть лучше, чем Exchanger.

2 голосов
/ 17 июля 2016

Давайте сосредоточимся на ключевой точке. Обменник: это точка встречи, где два потока могут обмениваться объектами. SynchQueue: это очередь!Один поток помещает и ждет, пока другой поток не появится. Exchanger является двунаправленным SyncQueue

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...