Синхронизированная очередь?

У меня есть две темы для онлайн-игры, которую я делаю. Один поток получает два числа X и Y, а другой поток отправляет числа X и Y всем, кто зашел на сервер. В основном мне нужна очередь, которая позволит первому потоку добавить 2D-массив в очередь и продолжать делать это, в то же время вытягивая массивы и удаляя массив из очереди для использования для отправки в другие игроки. Есть ли способ сделать это? Я знаю, что мне нужна синхронизированная очередь, но как ее синхронизировать, это называется блокирующей очередью?

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

-Дэн


person Code Doggo    schedule 31.01.2013    source источник
comment
Вы отметили blockingqueue, это не соответствует вашим потребностям?   -  person Miserable Variable    schedule 01.02.2013
comment
Любая BlockingQueue будет соответствовать спецификации.   -  person Bhaskar    schedule 01.02.2013


Ответы (1)


Блокирующая очередь — это очередь, в которой:

  1. добавление к нему элементов блокирует вызывающий поток в случае, если в очереди нет свободного места, до тех пор, пока элемент не будет удален (каким-либо другим потоком);
  2. удаляя из него элементы, блокирует вызывающий поток, если нет элементов для удаления, до тех пор, пока не будет добавлен элемент (каким-то другим потоком).

Чтобы добиться функциональности поточно-ориентированной (хотя и не обязательно синхронизированной) очереди, обычно используется одна из реализаций BlockingQueue, например LinkedBlockingQueue.

person yair    schedule 31.01.2013
comment
Вы добавляете больше путаницы, чем ясности (путем добавления точки безопасности потока и синхронизации). Это определенно кандидат на BlockingQueue. Синхронизированные оболочки следует использовать только в том случае, если требуется синхронизация на стороне клиента. Второй ваш пример опять БК - так почему бы не порекомендовать БК для начала.. - person Bhaskar; 01.02.2013
comment
@Bhaskar Я согласен, что BQ является рекомендуемым вариантом в этом случае, и я соответствующим образом отредактирую ответ. Однако, поскольку вопрос касается синхронизированной очереди, важно уточнить, что на самом деле требуется потокобезопасность и что LinkedBlockingQueue не синхронизируется. - person yair; 01.02.2013
comment
Подождите, почему блокирующая очередь не может быть использована для потокобезопасной очереди? Может ли работать java.util.concurrent.ConcurrentLinkedQueue‹E›? - person Code Doggo; 01.02.2013
comment
@DanielH, ConcurrentLinkedQueue =› не будет блокироваться при пустых/полных условиях, но допускает большую пропускную способность/одновременные операции, чем любые BlockingQueues. Зависит от ваших требований. И CLQ, и BQ являются потокобезопасными. - person Bhaskar; 01.02.2013
comment
@DanielH BQ может использоваться как потокобезопасная очередь. На самом деле он должен быть потокобезопасным. - person yair; 01.02.2013
comment
Последние вопросы. Когда я реализую LinkedBlockingQueue, должен ли я дать ему интерфейс Queue? Потому что, если я это сделаю (например: Queue‹int[][]›xy = new LinkedBlockingQueue‹int[][]›();), то по какой-то причине я не могу вызывать методы put и take. Только когда я использую интерфейс BlockingQueue, я могу использовать эти методы. Вы знаете, что происходит? Методы «взять и положить» находятся в классе LinkedBlockingQueue, что здесь происходит? - person Code Doggo; 01.02.2013
comment
Эти методы объявлены в интерфейсе BlockingQueue, а не в Queue. Да, вы должны использовать интерфейс BlockingQueue для ссылки на реализацию LinkedBlockingQueue. - person Bhaskar; 01.02.2013
comment
@DanielH put и take — это методы, добавленные в BlockingQueue, и не существующие в Queue. Это именно те методы, которые блокируют. Общий Queue не обязательно блокирует (например, ConcurrentLinkedQueue), и поэтому вы не можете получить доступ к этим методам через более общий интерфейс Queue. - person yair; 01.02.2013