2012-05-02 20 views
6

PriorityBlockingQueue öncelikli bir alanla kullanıyorum. Testimde, öncelikler için System#currentTime() kullanıyorum — bilgisayarla aynı öncelikleri, milisaniyelerin aynı olduğunu (veya bilgisayardaki milisaniyelerin bir hata payı gibi) o kadar çabuk elde ettiklerini elde ettim.Bir PriorityQueue neden bir Kuyruk gibi davranmıyor?

Öncelikleri aynı olduğunda, sıra bir yığın gibi davranır; bu garip görünüyor. Öğelerin öncelikleri aynı olduğunda, sıra normal bir sıra (yani, LIFO davranışından ziyade FIFO) gibi davranmasını sağlayan bir alternatif var mı?

cevap

11

Bu sınıftaki işlemler, eşit öncelikli öğelerin sipariş edilmesiyle ilgili hiçbir garanti vermez. Bir siparişi zorlamanız gerekiyorsa, birincil öncelik değerlerinde bağları koparmak için ikincil bir anahtar kullanan özel sınıflar veya karşılaştırıcılar tanımlayabilirsiniz.

PriorityBlockingQueue docs themselves

bu bilgi verin, gerekirse nasıl etrafında almak için.

+1

Dokümanları görün, ancak bir yığın değil bir sıra oluşturmak için zaten bir yardımcı program sınıfı olması beklenir. Eğer sıraya koyarsam, arkaya gitmeli ve daha yüksek bir önceliğe sahipse kuyruğa atlamalıdır. – Ben

+2

Neden? Kullanıcıların çoğu bir PriorityBlockingQueue öğesini farklı öncelikler ile kullanabilirler –

+2

Yığın bir sıra olmadığı için mi yoksa sadece semantik mi? – Ben

2

Öncelik sırasının eşit eleman alma sırasını garanti etmediğini düşünüyorum. Bir seçenek önceliği daha karmaşık hale getirmektir - öğeyi önceliği ile birlikte iterek kuyruğun boyutunun negatifini itin ve bu değerleri eşit öncelikli öğeler için karşılaştırın.

1

Oluşturma süresini hesaba katan kendi Karşılaştırıcınızla birlikte bir PriorityBlockingQueue oluşturmanız yeterlidir (bkz. http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/PriorityBlockingQueue.html#PriorityBlockingQueue(int, java.util.Comparator)). Anahtarlarınızı basit Tarih öğesinden bir Tarih ve sayaç sınıfına dönüştürmeniz gerekebilir; burada, her yaratılışla (yeni anahtar sınıfınızın statik alanı) global olarak artırılacak; Bu gerçekten FIFO değil, daha önce First First First Out düzenlendi. Veya yalnızca kendi PriorityQueueFifo sınıfınızı uygulayın.

0

Diğer bir çözüm de, öncelikli olarak kullandığınız ve her ekleme işleminde arttığınız testlerde bir sayaç bulundurmaktır. Bu şekilde öncelik sıranız, testlerinizde FIFO siparişi verecek, ancak keyfi bir öncelik sırasına benzeyecektir.

İlgili konular