如果多个线程同时迭代一个
HashMap
对象,而且没有进行修改,是否有可能出现竞态条件?如果您可以保证在遍历 HashMap 期间没有其他线程修改它,则不存在竞争问题。
不,这完全没问题。只要所有读操作与所有写操作同步,并且所有写操作相互同步,那么并发读操作是没有害处的;因此,如果根本不存在写操作,则所有并发访问都是安全的。
没关系的。但是如果任何一个线程添加或删除了一个项目,这将在任何其他正在迭代HashMap(实际上是任何集合)的线程中抛出异常。
如果您要重复迭代Map,您可能会发现通过迭代数组副本会稍微快一些。
private final HashMap<String, String> properties = new HashMap<String, String>();
private volatile Map.Entry<String, String>[] propertyEntries = null;
private void updatePropertyEntries() {
propertyEntries = properties.entrySet().toArray(new Map.Entry[properties.size()]);
}
{
// no objects created
for (Map.Entry<String, String> entry : propertyEntries) {
}
}
顺便说一句:您可以使用此模式在多个线程中遍历并修改/替换propertyEntries的一个线程。
HashMap
上的每个Iterator
都是在每个线程的 堆栈 上 本地 声明和分配的。 - 象嘉道