多个线程在同一个映射上迭代

时间:2012-03-08 10:32:17

标签: java multithreading

我最近在Java中编写了一个并发程序,并遇到了一个困境:假设你有一个全局数据结构,它是常规的非同步,非并发库,如HashMap的一部分。允许多个线程在不同的交错周期内迭代整个集合(只是读取,没有修改)是否可以,即当thread2在同一个地图上获取迭代器时,thread1可能会重复一半?

4 个答案:

答案 0 :(得分:12)

没关系。能够做到这一点是创建迭代器这样的接口的原因。迭代集合的每个线程都有自己的迭代器实例,它保持其状态(例如,您现在处于迭代过程中的位置)。

这允许多个线程同时迭代同一个集合。

答案 1 :(得分:7)

只要没有作家,它应该没问题。

此问题类似于readers-writer lock,其中允许多个读者从数据中读取数据,但在作者“拥有”锁定时不会读取数据。对于同时读取的倍数,没有并发问题。 [data race只有在您至少有一次写入时才会出现。

答案 2 :(得分:4)

只有在尝试对数据结构进行并发修改时才会出现问题。

例如,如果一个线程正在迭代Map的内容,而另一个线程从该集合中删除元素,那么您将面临严重的麻烦。

如果确实需要一些线程来安全地修改该集合,Java提供了这样做的机制,即ConcurrentHashMap。

ConcurrentHashMap in Java?

还有Hashtable,它具有与HashMap相同的接口,但是已经同步,虽然目前不建议使用它(不推荐使用),因为当元素数量变大时它的性能会受到影响(与ConcurrentHashMap相比,它不需要锁定整个Collection)。

如果您碰巧有一个未同步的Collection并且您需要在其上面读取和写入多个线程,您可以使用Collections.synchronizedMap(Map)来获取它的同步版本。

答案 3 :(得分:2)

以上答案肯定是好建议。通常,在使用并发线程编写Java时,只要不修改数据结构,就不必担心多个线程同时读取该结构。

如果您将来遇到类似的问题,除了可以同时修改全局数据结构之外,我建议编写一个所有线程用来访问和修改结构的Java类。这个类可以使用synchronized方法或锁来实现自己的并发方法。 Java教程对Java的并发机制有很好的解释。我亲自完成了这项工作并且相当直接。