2012-06-19 22 views
9

Şu anda bir üretici/tüketici iş parçacığı oluşturmaya çalışıyorum, üretici iş parçacığı, olası tüm harf kombinasyonlarından geçiyor ve kendi MD5 karmalarını yaratıyor. Daha sonra her bir kombinasyon ve onun karması HashMap<String,String>'a konur. Şimdi benim tüketici iş parçacığımda,vb. Queue gibi değerlerini kaldırarak, poll() numaralı telefonu arayarak, hem karma kombinasyonu hem de karma özelliğini görebilme yeteneğimi kullanmam için Queue<> koleksiyonunu hashmap'da kullanmak istiyorum. Bunu yapmak için nasıl giderim? HashMap var, ama nasıl 'yapmak' ya da bir kuyruk olarak çevirmek bilmiyorum. Teşekkürler. Bu anahtar/değer çiftleri depolar, ancak aynı zamanda sokulmuştur sırayı hatırlar -HashMap seti için bir Kuyruk oluşturulabilir mi?

cevap

7

Kodunuzun iş parçacığı güvenliğini kullanmadan bir HashMap kullanmamalısınız. Else, bir Live-lock ile bitebilirsiniz.

Haritanızı tuşların girildiği sırayla yineleyebilmek için LinkedHashMap kullanabilirsiniz.

Map m = Collections.synchronizedMap(new LinkedHashMap(...)); 

bu (özel bir şey) gibi girdileri itecek yapımcı:

while (someCondition) { 
    Map.Entry nextEntry = null; 

    // This block is equivalent to polling 
    { 
     synchronized(s) { 
      Iterator i = s.iterator(); // Must be in the synchronized block 
      if (i.hasNext()) { 
       nextEntry = i.next(); 
       i.remove(); 
      } 
     } 
    } 

    if (nextEntry != null) { 
     // Process the entry 
     ... 
    } else { 
     // Sleep for some time 
     ... 
    } 
    // process 
} 
+0

Teşekkürler, bu bir çekicilik çalıştı ve uygulamak için hızlı, kolay ve net oldu –

5

LinkedHashMap tip HashMap ve Queue bir kombinasyonu gibi. Bu tam olarak aradığınız türde olabilir. Açık poll() işlevi yoktur, ancak LinkedHashMap üzerinden bir yineleyici alırsanız, öğeleri eklendikleri sırayla ziyaret edersiniz. İlk eleman size geri verecektir

public <KeyType, ValueType> KeyType first(LinkedHashMap<KeyType, ValueType> map) { 
    assert !map.isEmpty(); 
    return map.iterator().next(); 
} 

: Muhtemelen sonra böyle bir fonksiyon yazabiliriz. Sadece uygun şekilde senkronize ettiğinizden emin olun.

Alternatif olarak, sadece bir yardımcı sınıf Pair tanımlayan ve daha sonra kuyrukta Pair s depolayarak bir Queue içinde anahtar/değer çiftleri depolamak düşünebiliriz.

Bu yardımcı olur umarız!

+0

Güzel, bu yüzden bazı SyncObject gerek sadece olacaktır:

m.put(key, object) 

tüketici böyle girdileri anket ediyorum Tüketici tarafında LinkedHashMap'ten okumak mümkün olduğunda sinyal. –

+0

Merhaba, LinkedHashMap iş parçacığı güvenli değil ve Queue tipinde değil. – sperumal

+0

@ sperumal - Bunlardan hiçbirinin böyle olmadığına asla karar vermedim. OP'nin senkronizasyon kodunu sağlayacağını varsaydım. Ayrıca, 'Queue 'türünde olması gereken herhangi bir gereklilik olduğuna inanmıyorum; OP'nin sorusu bundan hiç bahsetmez. Bu bir gereklilikse, bu yaklaşım kesinlikle işe yaramayacaktır. – templatetypedef

4

Sana EntrySet bir Kuyruk yaratmak önermek -

Queue<EntrySet<String,String>> queue = new SynchronousQueue<EntrySet<String,String>>(); 
for (EntrySet<String,String> entry:map.entrySet()) { 
    queue.add(entry); 
} 

Sen boş olmayan bu tür LinkedBlockingQueue olarak söz konusu unsurları ve sadece prdocuer bekler koymak sağlayan kuyruğun başka tür kullanarak düşünebilirsiniz.
Üretici, daha sonra gerekirse bir EntrySet nesnelerini temel alan bir haritayı yeniden oluşturabilecektir.

+0

Hmm Bu iyi bir yöntem gibi görünüyor. Teşekkürler, deneyeceğim. Bir soru bu iş parçacığı güvenli mi? –

İlgili konular