2012-02-24 100 views
3

如果多个线程同时重复一个HashMap对象,没有修改它,是否有机会的竞争条件?同时迭代HashMap对象是否线程安全?

+1

很明显,如果没有人正在修改任何东西,不能有任何数据竞赛 – Voo 2012-02-24 02:10:51

+3

@Voo:我不会说“显然”。这是事实,因为JDK在这方面设计得很好,但设计一个API似乎是可能的,其中看似只读操作涉及内部临时修改,但无法安全地同时完成。 (事实上​​,我出于各种原因自己创建了这样的API。)所以这是一个合理的问题。 – ruakh 2012-02-24 02:13:33

+0

线程是否使用相同的迭代器? – 2012-02-24 02:15:08

回答

4

没有竞争,如果你可以保证没有其他线程在迭代时修改这个HashMap。

3

不,这是完美的。只要所有读取与所有写入同步,并且所有写入都彼此同步,则并发读取不会造成任何损害;所以如果根本没有写入,那么所有并发访问都是安全的。

+1

如果未修改,则不需要同步。 – 2012-02-24 08:31:01

+1

@PeterLawrey:确实如此。 – ruakh 2012-02-24 12:35:04

0

如果您要重复迭代一个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,同时用这种模式在许多线程中迭代。

1

这将是对的。但是,如果任何线程添加或删除一个项目,这将抛出异常在任何其他线程只是迭代HashMap(实际上任何收集)