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