Hayır, yöntemlerin eşitlenmesi gerekmez ve herhangi bir yöntem tanımlamanız gerekmez; zaten ConcurrentLinkedQueue'dalar, sadece onları kullanın. ConcurrentLinkedQueue, ihtiyacınız olan tüm kilitleme ve diğer işlemleri dahili olarak yapar; üreticiniz / üreticileriniz kuyruğa veri ekler ve tüketicileriniz bunun için anket yapar.
Önce sıranızı oluşturun:
Queue<YourObject> queue = new ConcurrentLinkedQueue<YourObject>();
Şimdi, üretici / tüketici nesnelerinizi nerede yaratıyor olursanız olun, sıraya geçin, böylece nesnelerini koyabilecekleri bir yere sahip olurlar (bunun yerine bunun için bir ayarlayıcı kullanabilirsiniz, ancak ben bir kurucuda bu tür şeyler yapmayı tercih ederim):
YourProducer producer = new YourProducer(queue);
ve:
YourConsumer consumer = new YourConsumer(queue);
ve yapımcınıza bir şeyler ekleyin:
queue.offer(myObject);
ve tüketicinizdeki eşyaları çıkarın (kuyruk boşsa, anket () boş dönecektir, bu yüzden kontrol edin):
YourObject myObject = queue.poll();
Daha fazla bilgi için bkz . Javadoc
DÜZENLE:
Kuyruğun boş olmaması için beklemeyi engellemeniz gerekiyorsa, muhtemelen bir LinkedBlockingQueue ve take () yöntemini kullanmak istersiniz . Bununla birlikte, LinkedBlockingQueue maksimum kapasiteye sahiptir (varsayılan olarak Integer.MAX_VALUE şeklindedir, bu iki milyardan fazladır) ve bu nedenle koşullarınıza bağlı olarak uygun olabilir veya olmayabilir.
Kuyruğa bir şeyler koyan yalnızca bir iş parçacığınız varsa ve kuyruktan bir şeyler alan başka bir iş parçacığınız varsa, ConcurrentLinkedQueue muhtemelen gereğinden fazla olur. Sıraya aynı anda erişen yüzlerce hatta binlerce iş parçacığına sahip olabileceğiniz zamanlar için daha fazlası. İhtiyaçlarınız muhtemelen aşağıdakiler kullanılarak karşılanacaktır:
Queue<YourObject> queue = Collections.synchronizedList(new LinkedList<YourObject>());
Bunun bir artısı, örneğe (kuyruk) kilitlenmesidir, böylece bileşik işlemlerin atomikliğini sağlamak için kuyrukta senkronizasyon yapabilirsiniz (Jared tarafından açıklandığı gibi). Tüm işlemler örnek üzerinde kilitleme OLMADAN (java.util.concurrent.atomic değişkenler kullanılarak) yapıldığından, bunu ConcurrentLinkedQueue ile YAPAMAZSINIZ. Kuyruk boşken bloke etmek istiyorsanız bunu yapmanıza gerek YOKTUR, çünkü poll () kuyruk boşken basitçe null döndürecektir ve anket () atomiktir. Anketin () boş döndürüp döndürmediğini kontrol edin. Varsa, bekleyin (), ardından tekrar deneyin. Kilitlemeye gerek yok.
En sonunda:
Dürüst olmak gerekirse, sadece LinkedBlockingQueue kullanırım. Başvurunuz için hala aşırı, ancak büyük olasılıkla iyi çalışacak. Yeterince performanslı değilse (PROFİL!), Her zaman başka bir şey deneyebilirsiniz ve bu, HERHANGİ bir senkronize şeyle uğraşmanıza gerek olmadığı anlamına gelir:
BlockingQueue<YourObject> queue = new LinkedBlockingQueue<YourObject>();
queue.put(myObject);
YourObject myObject = queue.take();
Diğer her şey aynı. Koyma muhtemelen engellemez, çünkü iki milyar nesneyi sıraya koyma ihtimaliniz yok.