No, no es necesario sincronizar los métodos y no es necesario definir ningún método; ya están en ConcurrentLinkedQueue, solo utilícelos. ConcurrentLinkedQueue realiza todas las operaciones de bloqueo y otras operaciones que necesita internamente; su (s) productor (es) agregan datos a la cola, y sus consumidores los sondean.
Primero, crea tu cola:
Queue<YourObject> queue = new ConcurrentLinkedQueue<YourObject>();
Ahora, donde sea que esté creando sus objetos de productor / consumidor, pase la cola para que tengan un lugar donde poner sus objetos (podría usar un establecedor para esto, pero prefiero hacer este tipo de cosas en un constructor):
YourProducer producer = new YourProducer(queue);
y:
YourConsumer consumer = new YourConsumer(queue);
y agregarle cosas en su productor:
queue.offer(myObject);
y sacar cosas en su consumidor (si la cola está vacía, poll () devolverá nulo, así que verifíquelo):
YourObject myObject = queue.poll();
Para obtener más información, consulte el Javadoc
EDITAR:
Si necesita bloquear la espera de que la cola no esté vacía, probablemente desee utilizar un LinkedBlockingQueue y usar el método take (). Sin embargo, LinkedBlockingQueue tiene una capacidad máxima (el valor predeterminado es Integer.MAX_VALUE, que es más de dos mil millones) y, por lo tanto, puede o no ser apropiado según sus circunstancias.
Si solo tiene un hilo que pone cosas en la cola y otro hilo que saca cosas de la cola, ConcurrentLinkedQueue probablemente sea excesivo. Es más para cuando puede tener cientos o incluso miles de subprocesos accediendo a la cola al mismo tiempo. Es probable que sus necesidades se satisfagan utilizando:
Queue<YourObject> queue = Collections.synchronizedList(new LinkedList<YourObject>());
Una ventaja de esto es que se bloquea en la instancia (cola), por lo que puede sincronizar en la cola para garantizar la atomicidad de las operaciones compuestas (como lo explicó Jared). NO PUEDE hacer esto con un ConcurrentLinkedQueue, ya que todas las operaciones se realizan SIN bloquear la instancia (usando variables java.util.concurrent.atomic). NO necesitará hacer esto si desea bloquear mientras la cola está vacía, porque poll () simplemente devolverá nulo mientras la cola está vacía, y poll () es atómico. Compruebe si poll () devuelve nulo. Si es así, espere () y vuelva a intentarlo. No es necesario bloquear.
Finalmente:
Honestamente, solo usaría un LinkedBlockingQueue. Todavía es excesivo para su aplicación, pero es probable que funcione bien. Si no tiene el rendimiento suficiente (¡PERFIL!), Siempre puede probar algo más, y significa que no tiene que lidiar con NINGÚN elemento sincronizado:
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.
Todo lo demás es lo mismo. Put probablemente no se bloqueará, porque no es probable que coloque dos mil millones de objetos en la cola.