Нет, методы не нужно синхронизировать, и вам не нужно определять какие-либо методы; они уже находятся в ConcurrentLinkedQueue, просто используйте их. ConcurrentLinkedQueue выполняет все необходимые вам операции блокировки и другие операции; ваш производитель (и) добавляет данные в очередь, и ваши потребители опрашивают их.
Сначала создайте свою очередь:
Queue<YourObject> queue = new ConcurrentLinkedQueue<YourObject>();
Теперь, где бы вы ни создавали свои объекты производителя / потребителя, передайте очередь, чтобы у них было куда поместить свои объекты (вместо этого вы можете использовать сеттер, но я предпочитаю делать такие вещи в конструкторе):
YourProducer producer = new YourProducer(queue);
а также:
YourConsumer consumer = new YourConsumer(queue);
и добавьте в него что-нибудь в своем продюсере:
queue.offer(myObject);
и извлеките материал из своего потребителя (если очередь пуста, poll () вернет null, поэтому проверьте его):
YourObject myObject = queue.poll();
Для получения дополнительной информации см. Javadoc
РЕДАКТИРОВАТЬ:
Если вам нужно заблокировать ожидание, пока очередь не станет пустой, вы, вероятно, захотите использовать LinkedBlockingQueue и использовать метод take (). Однако LinkedBlockingQueue имеет максимальную емкость (по умолчанию Integer.MAX_VALUE, что превышает два миллиарда) и, следовательно, может или не может быть подходящим в зависимости от ваших обстоятельств.
Если у вас есть только один поток, помещающий данные в очередь, а другой поток извлекает данные из очереди, ConcurrentLinkedQueue, вероятно, является излишним. Это больше для случаев, когда у вас могут быть сотни или даже тысячи потоков, обращающихся к очереди одновременно. Ваши потребности, вероятно, будут удовлетворены с помощью:
Queue<YourObject> queue = Collections.synchronizedList(new LinkedList<YourObject>());
Плюс этого в том, что он блокирует экземпляр (очередь), поэтому вы можете синхронизировать по очереди, чтобы гарантировать атомарность составных операций (как объяснил Джаред). Вы НЕ МОЖЕТЕ сделать это с помощью ConcurrentLinkedQueue, поскольку все операции выполняются БЕЗ блокировки экземпляра (с использованием переменных java.util.concurrent.atomic). Вам НЕ нужно делать это, если вы хотите заблокировать, пока очередь пуста, потому что poll () просто вернет null, пока очередь пуста, а poll () является атомарным. Проверьте, возвращает ли poll () значение null. Если это так, подождите () и попробуйте еще раз. Не нужно запирать.
В заключение:
Честно говоря, я бы просто использовал LinkedBlockingQueue. Это все еще излишне для вашего приложения, но есть вероятность, что оно будет работать нормально. Если он недостаточно эффективен (ПРОФИЛЬ!), Вы всегда можете попробовать что-то еще, и это означает, что вам не нужно иметь дело с ЛЮБЫМ синхронизированным материалом:
BlockingQueue<YourObject> queue = new LinkedBlockingQueue<YourObject>();
queue.put(myObject);
YourObject myObject = queue.take();
В остальном все то же самое. Put, вероятно , не будет блокировать, потому что вы вряд ли поместите в очередь два миллиарда объектов.