对集合进行线程安全迭代

MRa*_*ser 19 java collections multithreading iterator thread-safety

我们都知道在使用时Collections.synchronizedXXX(例如synchronizedSet())我们获得了底层集合的同步"视图".

但是,这些包装器生成方法的文档指出,在使用迭代器迭代集合,我们必须在集合上显式同步.

您选择哪个选项来解决此问题?

我只能看到以下方法:

  1. 按照文档说明:对集合进行同步
  2. 在致电之前克隆集合 iterator()
  3. 使用迭代器是线程安全的集合(我只知道CopyOnWriteArrayList/ Set)

并且作为一个额外的问题:当使用同步视图时 - 使用foreach/Iterable线程安全吗?

Jon*_*eet 26

你已经真的回答了你的奖金问题:不,使用增强的for循环不安全的 - 因为它使用了迭代器.

至于哪种方法最合适 - 它实际上取决于你的背景:

  • 写作很少见吗?如果是这样,CopyOnWriteArrayList可能是最合适的.
  • 集合相当小,迭代速度快吗?(即你在循环中没有做太多的工作)如果是这样,同步可能会很好 - 特别是如果这种情况不常发生(即你不会对集合有太多的争论).
  • 如果你正在做很多工作并且不想阻止其他线程同时工作,那么克隆集合的命中可能是可以接受的.

  • @MRalwasser:除了只使用数组索引的数组外,它受规范的保证.请参阅JLS的14.14.2节:http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.14.2 (4认同)
  • 是否保证foreach将始终使用迭代器()或特定于此实现? (3认同)

Sto*_*ica 6

取决于您的访问模式.如果您具有较低的并发性和频繁写入,则1将具有最佳性能.如果您具有高并发和不频繁的写入,则3将具有最佳性能.选项2在几乎所有情况下都会表现不佳.

foreach电话iterator(),所以完全相同的事情适用.