现在我正在尝试创建一个生产者/消费者线程,生产者线程遍历所有可能的字母组合并创建它们各自的MD5哈希值。然后将每个组合及其哈希值放入HashMap<String,String>
。现在在我的消费者线程中,我希望能够在hashmap上使用Queue<>
集合,以便我的消费者线程可以调用poll()
等,从而删除atc,如Queue
,但仍然给我在调用poll()
时看到组合及其哈希的能力我将如何做到这一点?我有HashMap
但不知道如何“制作”或将其作为队列投射。
感谢。
答案 0 :(得分:9)
如果不处理代码的线程安全性,则不应使用HashMap。否则,您可能会以Live-lock结束。
为了能够按照插入键的顺序迭代Map,可以使用LinkedHashMap。
Map m = Collections.synchronizedMap(new LinkedHashMap(...));
制作人会像这样推送条目(没什么特别的):
m.put(key, object)
消费者会轮询这样的条目:
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
}
答案 1 :(得分:5)
LinkedHashMap
类型类似于HashMap
和Queue
的组合 - 它存储键/值对,但也会记住其中的顺序他们被插入。这可能正是您正在寻找的类型。没有明确的poll()
函数,但是如果你得到LinkedHashMap
上的迭代器,你将按照它们被添加的顺序访问元素。然后你可以编写一个这样的函数:
public <KeyType, ValueType> KeyType first(LinkedHashMap<KeyType, ValueType> map) {
assert !map.isEmpty();
return map.iterator().next();
}
将返回第一个元素。只需确保正确同步。
或者,您可以考虑通过定义帮助程序类Queue
然后将Pair
存储在队列中来将键/值对存储在Pair
中。
希望这有帮助!
答案 2 :(得分:4)
我建议你创建一个EntrySet队列 -
Queue<EntrySet<String,String>> queue = new SynchronousQueue<EntrySet<String,String>>();
for (EntrySet<String,String> entry:map.entrySet()) {
queue.add(entry);
}
您可以考虑使用另一种类型的队列,它允许您放置元素,只有prdocuer在非空的情况下等待,例如LinkedBlockingQueue。
然后,如果需要,生产者将能够基于EntrySet对象重构地图。