Ні, методи не потрібно синхронізувати, і вам не потрібно визначати будь-які методи; вони вже знаходяться в 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
Редагувати:
Якщо вам потрібно заблокувати очікування, коли черга не буде порожньою, ви, ймовірно, хочете скористатися LinkedBlockingQueue і скористатися методом take (). Однак LinkedBlockingQueue має максимальну ємність (за замовчуванням Integer.MAX_VALUE, що перевищує два мільярди), і, отже, може бути або не відповідати вашим обставинам.
Якщо у вас є лише один потік, який розміщує речі в черзі, а інший потік виводить речі з черги, ConcurrentLinkedQueue, ймовірно, надмірний. Це більше для того, коли у вас можуть бути сотні або навіть тисячі потоків, що одночасно отримують доступ до черги. Можливо, ваші потреби будуть задоволені, використовуючи:
Queue<YourObject> queue = Collections.synchronizedList(new LinkedList<YourObject>());
Плюсом цього є те, що він блокується на екземплярі (черзі), тому ви можете синхронізуватися в черзі, щоб забезпечити атомність складених операцій (як пояснив Джаред). Ви НЕ МОЖЕТЕ зробити це за допомогою ConcurrentLinkedQueue, оскільки всі операції виконуються БЕЗ блокування екземпляра (за допомогою змінних java.util.concurrent.atomic). ЦЕ НЕ буде потрібно робити, якщо ви хочете заблокувати, поки черга порожня, тому що опитування () просто поверне нуль, поки черга порожня, а опитування () - атомне. Перевірте, чи опитування () повертає нуль. Якщо це так, зачекайте (), тоді спробуйте ще раз. Не потрібно блокувати.
Нарешті:
Чесно кажучи, я просто скористався 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.
Все інше те саме. Покладіть, ймовірно , не буде блокуватись, оскільки ви, ймовірно, не поставите два мільярди об’єктів у чергу.