Nie, metody nie muszą być synchronizowane i nie musisz definiować żadnych metod; są już w ConcurrentLinkedQueue, po prostu ich używaj. ConcurrentLinkedQueue wykonuje wewnętrznie wszystkie operacje blokowania i inne potrzebne; Twoi producenci dodają dane do kolejki, a Twoi konsumenci sondują je.
Najpierw utwórz kolejkę:
Queue<YourObject> queue = new ConcurrentLinkedQueue<YourObject>();
Teraz, gdziekolwiek tworzysz swoje obiekty producenta / konsumenta, przekaż kolejkę, aby mieli gdzie umieścić swoje obiekty (zamiast tego możesz użyć do tego ustawiacza, ale ja wolę zrobić to w konstruktorze):
YourProducer producer = new YourProducer(queue);
i:
YourConsumer consumer = new YourConsumer(queue);
i dodaj do tego rzeczy w swoim producencie:
queue.offer(myObject);
i wyjmij rzeczy z twojego konsumenta (jeśli kolejka jest pusta, poll () zwróci null, więc sprawdź to):
YourObject myObject = queue.poll();
Aby uzyskać więcej informacji, zobacz Javadoc
EDYTOWAĆ:
Jeśli chcesz zablokować oczekiwanie, aż kolejka nie będzie pusta, prawdopodobnie chcesz użyć LinkedBlockingQueue i metody take (). Jednak LinkedBlockingQueue ma maksymalną pojemność (domyślnie Integer.MAX_VALUE, czyli ponad dwa miliardy), a zatem może być odpowiedni lub nie w zależności od okoliczności.
Jeśli masz tylko jeden wątek, który umieszcza rzeczy w kolejce, a inny wątek pobiera rzeczy z kolejki, ConcurrentLinkedQueue jest prawdopodobnie przesadą. Jest to bardziej przydatne, gdy możesz mieć setki lub nawet tysiące wątków uzyskujących dostęp do kolejki w tym samym czasie. Twoje potrzeby prawdopodobnie zostaną zaspokojone poprzez zastosowanie:
Queue<YourObject> queue = Collections.synchronizedList(new LinkedList<YourObject>());
Zaletą tego jest to, że blokuje się na instancji (kolejce), dzięki czemu można synchronizować w kolejce, aby zapewnić atomowość operacji złożonych (jak wyjaśnił Jared). NIE MOŻESZ tego zrobić z ConcurrentLinkedQueue, ponieważ wszystkie operacje są wykonywane BEZ blokowania instancji (przy użyciu zmiennych java.util.concurrent.atomic). NIE będziesz musiał tego robić, jeśli chcesz blokować, gdy kolejka jest pusta, ponieważ funkcja poll () zwróci wartość null, gdy kolejka jest pusta, a funkcja poll () jest atomowa. Sprawdź, czy poll () zwraca null. Jeśli tak, poczekaj () i spróbuj ponownie. Nie ma potrzeby blokowania.
Wreszcie:
Szczerze, po prostu użyłbym LinkedBlockingQueue. Nadal jest to przesada dla twojej aplikacji, ale są szanse, że będzie działać dobrze. Jeśli nie jest wystarczająco wydajny (PROFIL!), Zawsze możesz spróbować czegoś innego, a to oznacza, że nie musisz zajmować się ŻADNYMI zsynchronizowanymi rzeczami:
BlockingQueue<YourObject> queue = new LinkedBlockingQueue<YourObject>();
queue.put(myObject);
YourObject myObject = queue.take();
Cała reszta jest taka sama. Opcja Put prawdopodobnie nie zostanie zablokowana, ponieważ prawdopodobnie nie umieścisz dwóch miliardów obiektów w kolejce.