Não, os métodos não precisam ser sincronizados e você não precisa definir nenhum método; eles já estão em ConcurrentLinkedQueue, basta usá-los. ConcurrentLinkedQueue faz todo o bloqueio e outras operações de que você precisa internamente; o (s) seu (s) produtor (es) adiciona (m) dados à fila e seus consumidores fazem pesquisas para isso.
Primeiro, crie sua fila:
Queue<YourObject> queue = new ConcurrentLinkedQueue<YourObject>();
Agora, onde quer que você esteja criando seus objetos produtor / consumidor, passe na fila para que eles tenham um lugar para colocar seus objetos (você poderia usar um setter para isso, mas eu prefiro fazer esse tipo de coisa em um construtor):
YourProducer producer = new YourProducer(queue);
e:
YourConsumer consumer = new YourConsumer(queue);
e adicione coisas a ele em seu produtor:
queue.offer(myObject);
e retire as coisas em seu consumidor (se a fila estiver vazia, poll () retornará nulo, então verifique):
YourObject myObject = queue.poll();
Para mais informações veja o Javadoc
EDITAR:
Se você precisa bloquear a espera para que a fila não fique vazia, você provavelmente deseja usar um LinkedBlockingQueue e usar o método take (). No entanto, LinkedBlockingQueue tem uma capacidade máxima (o padrão é Integer.MAX_VALUE, que é mais de dois bilhões) e, portanto, pode ou não ser apropriado dependendo das circunstâncias.
Se você tiver apenas um thread colocando coisas na fila e outro thread retirando coisas da fila, ConcurrentLinkedQueue provavelmente é um exagero. É mais para quando você pode ter centenas ou mesmo milhares de threads acessando a fila ao mesmo tempo. Provavelmente, suas necessidades serão atendidas usando:
Queue<YourObject> queue = Collections.synchronizedList(new LinkedList<YourObject>());
Uma vantagem disso é que ele bloqueia na instância (fila), para que você possa sincronizar na fila para garantir a atomicidade das operações compostas (conforme explicado por Jared). Você NÃO PODE fazer isso com um ConcurrentLinkedQueue, pois todas as operações são feitas SEM bloqueio na instância (usando variáveis java.util.concurrent.atomic). Você NÃO precisará fazer isso se quiser bloquear enquanto a fila estiver vazia, porque poll () simplesmente retornará nulo enquanto a fila estiver vazia, e poll () é atômico. Verifique se poll () retorna nulo. Se isso acontecer, espere () e tente novamente. Não há necessidade de bloquear.
Finalmente:
Honestamente, eu apenas usaria um LinkedBlockingQueue. Ainda é um exagero para o seu aplicativo, mas provavelmente funcionará bem. Se não tiver desempenho suficiente (PERFIL!), Você sempre pode tentar outra coisa, e isso significa que você não precisa lidar com NENHUM material 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.
Tudo o resto é o mesmo. Put provavelmente não bloqueará, porque você provavelmente não colocará dois bilhões de objetos na fila.