Какая коллекция поддерживает несколько одновременных вставок? - PullRequest
3 голосов
/ 22 июня 2010

Мы разрабатываем Java-приложение с несколькими рабочими потоками.Эти потоки должны будут доставлять много результатов вычислений в наш поток пользовательского интерфейса.Порядок доставки результатов не имеет значения.

В настоящий момент все потоки просто помещают свои результаты в синхронизированный стек - но это означает, что каждый поток должен ждать других потоков, прежде чем результаты будут доставлены.

Существует ли структура данных, которая поддерживает одновременные вставки, причем каждая вставка выполняется в постоянное время?

Спасибо,

Мартин

Ответы [ 5 ]

10 голосов
/ 22 июня 2010

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

ArrayBlockingQueue лучше для уменьшения конкуренции и с меньшими накладными расходами.

Редактировать: Хотя это не то, что вы просили. Одновременно вставляет? Вы можете назначить каждому потоку одну выходную очередь (скажем, ArrayBlockingQueue), а затем поток пользовательского интерфейса опрашивает отдельные очереди. Тем не менее, я думаю, вам будет достаточно одной из двух приведенных выше реализаций Queue.

3 голосов
/ 22 июня 2010

Прямо сейчас, все темы просто нажимают их результаты на синхронизированный Стек - но это означает, что каждый поток должен ждать других потоков прежде чем результаты могут быть доставлены.

У вас есть доказательства того, что это действительно проблема? Если вычисления, выполняемые этими потоками, являются даже хотя бы немного сложными (и у вас нет буквально миллионов потоков), то конфликт блокировок в стеке результатов просто не является проблемой, потому что, когда какой-либо поток предоставляет свои результаты, другие, скорее всего, заняты своими вычислениями.

1 голос
/ 22 июня 2010

Сделайте шаг назад и оцените, является ли производительность ключевым моментом при проектировании. Не думай, знай: профилирование поддерживает это?

Если нет, то я бы сказал, что большее беспокойство вызывает ясность и удобочитаемость дизайна, а не введение нового кода для сопровождения. Так уж получилось, что если вы используете Swing, есть библиотека для выполнения точно того, что вы пытаетесь сделать, называемая SwingWorker.

0 голосов
/ 22 июня 2010

Два других шаблона, которые вы можете посмотреть:

  • , каждый поток имеет свою собственную коллекцию, при опросе он возвращает коллекцию и создает новую, поэтому коллекция содержит тольконезавершенные пункты между опросами.Поток должен защищать операции над своей коллекцией, но между потоками нет конфликта.Это блокировка (каждый поток не может добавить свою коллекцию, пока поток пользовательского интерфейса извлекает из нее обновления), но может уменьшить конфликт (нет конкуренции между потоками).

  • каждый поток имеет свою собственную коллекциюи добавляет результаты в общую очередь, которая защищена с помощью Lock.tryLock ().Поток продолжает обработку, если ему не удается получить блокировку.Это снижает вероятность того, что поток заблокирует ожидание общей очереди.

0 голосов
/ 22 июня 2010

Взгляните на java.util.concurrent.ConcurrentLinkedQueue, java.util.concurrent.ConcurrentHashMap или java.util.concurrent.ConcurrentSkipListSet.Они могут делать то, что вам нужно.Например, ConcurrentSkipListSet утверждает, что "ожидаемые средние log (n) временные затраты для операций contains, add и remove и их вариантов. Операции вставки, удаления и доступабезопасно выполнять одновременно несколько потоков. "

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