Это зависит от реализации. Если для разных продуктов существуют отдельные очереди, каждая очередь должна быть защищена отдельным объектом блокировки (этот объект блокировки может сама очередь).
Также это зависит, если вы пишете реализацию для очереди, тогда вы можете решить, что объект Lock является частной переменной. При добавлении вы можете проверить, заполнена ли очередь, вы можете выбрать wait
для переменной частного замка. Как только любой объект будет потреблен, вы можете вызывать notifyall
(или notify
, хотя notifyall
предпочтительнее) на частном объекте блокировки. Аналогичным образом вы можете иметь логику и notify
, если потребители вызывают метод для извлечения элемента из очереди, когда он пуст. Таким образом, ваш класс очереди будет отвечать за блокировку и уведомление с использованием объекта private variable. Поскольку очередь имеет объект private var lovk, то каждый экземпляр очереди будет иметь свой отдельный объект Lock.
Другой способ заключается в том, что очередь является общей очередью, может быть ее не то, кто пишет очередь, тогда вам нужно будет защитить код, вызывающий методы для добавления и выбора. Если у вас есть отдельные очереди для разных продуктов (x, y и т. Д.), Вам понадобятся разные объекты Lock для каждой очереди. Это необходимо для предотвращения взаимоблокировок, это может произойти (если у нас нет объектов блокировки sepatrate), потребительX ожидает, что queueX будет иметь вставленный элемент (как пустой), а другой производительY не получает возможность вставлять в queueY (как его полный). Следовательно, вам нужны отдельные объекты блокировки.
Update
@TheCoder Если у вас есть только один производитель и потребитель как заинтересуют же вида продукции, то одна очередь в порядке. Теперь возникает вопрос об общем объекте, с которым оба должны взаимодействовать. Это зависит от реализации, если вы хотите, чтобы Queue позаботился об этом, Queue может иметь личное поле private Object monitor = new Object();
и может иметь метод, который синхронизируется 0SCи dequeue
на «мониторе».
Метод dequeue
Если очередь пуста, то вызовите monitor.wait()
внутри цикла while
до тех пор, пока очередь не будет пуста. Если очередь не пуста, то удалите объект из очереди и вызовите monitor.notifyAll();
Метод enqueue
, если очередь равна полному вызову monitor.wait()
в цикле while до тех пор, пока очередь не будет заполнена.Если очередь не заполнена, то добавить объект в очереди и вызвать monitor.notifyAll();
Если ваша реализация такой, который вы хотите очереди, чтобы не заботиться о Syncronization, то вы должны иметь общий объект, на котором Producrer
и Consumer
может синхронизироваться перед вызовом enqueue
и dequeue
на queue
. Этот общий объект может быть экземпляром queue
. wait
и notifyAll
необходимо вызвать внутри синхронизированного блока совместно используемого объекта.
Обычно вы используете реализацию параллельной очереди, которая обеспечивает как блокировку (безопасную публикацию, так и на самом деле), так и сторону уведомления. – BeeOnRope
Задача, которую я пытаюсь предпринять, - научить меня многопоточности, и поэтому я не использую ничего из параллельного пакета. – TheCoder
Ваш вопрос непонятен. Если у вас разные типы объектов и разные потребители, используйте две очереди. Возможно, вы должны разбить свой вопрос, по крайней мере, на два: один фокусируется на том, как создать параллельную очередь, и один для вашей идеи о том, что разные созданные/потребительские типы взаимодействуют с одной очередью. Они кажутся мне ортогональными. – BeeOnRope