我们有一个多线程应用程序,采用经典的生产者/消费者方法,使用 ConcurrentHashmap 队列。
消费者启动一个线程,该线程内部有一个无限循环,并发 HashMap 上有另一个嵌套循环,用于读取和删除每个已处理的项目。
我在问自己这段代码对于 map 上的“for”迭代和每个元素的“remove”是否安全/有效。
运行代码似乎正确...
new Thread(t.getContextName()+"-RespMsgThread") {
public void run() {
try {
do {
for (Entry<Integer, AbstractMessage> nodeEntry : t.getHtForResponse().entrySet())
{
--> Doing some stuff with the node Entry
// remove the node from the queue
t.getHtForResponse().remove(nodeEntry.getKey());
}
yield();
}
while (!t.isStopControllerRun());
} catch (InterruptedException ex) {
Context.getInstance().getLogger().info("ERROR: " + ExceptionUtils.getStackTrace(ex));
}
}
}.start();
最佳答案
是的,它完全安全/高效地尊重“for”迭代。有一个问题,因为 ConcurrentHashMap 的迭代器是弱一致的,您可以删除未处理的键的值(在您的情况下对节点 Entry 做一些事情)。
所以可以考虑调用方法
remove(Object key, Object value)
removes the entry for a key only if currently mapped to a given value.
而不是普通的remove(Object key)方法
关于具有 ConcurrentHashmap 策略的 Java 多线程消费者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56180764/