对ReadWriteLock受保护映射的缓慢交互:读取锁定,并发映射还是复制?

时间:2012-08-10 10:41:56

标签: java concurrency concurrent-collections

我有一张经常阅读但很少写入的地图。某些操作(可以是读取或写入)涉及需要以原子方式操作的多个对象,因此我使用ReadWriteLock来提高性能。

现在我可以选择将并发映射降级为普通的哈希映射,但我担心一些缓慢的迭代代码。

如果我降级了地图,那么长迭代器必须保持读锁定以避免并发访问异常。我认为这会长时间阻止写作线程。

由于某些迭代器对不一致的数据不敏感,我可以保留并发映射,以便迭代器可以与并发写入一起使用。但是,这会增加不必要的开销(从并发映射)到正确使用锁的操作。

或者,我可以实现类似于Read-on-write映射的东西,其中克隆整个(非并发)映射以进行写操作,以便现有迭代器继续在读锁之外工作。

显然,所有这些方法都是有效的,性能取决于实际的代码和设置。但是,我想知道是否有任何研究(所以我不必自己做实验)?

1 个答案:

答案 0 :(得分:5)

  

我有一张经常阅读但很少写入的地图。

在这种情况下,我会考虑实现写地图的副本。 e.g。

private final Map<Key, Value> map = ?* thread safe map */
private volatile Map<Key, Value> mapCopy = emptyMap();

// when you write
get lock
modify map
take a copy and store it in mapCopy
release lock

// when you read
Map<Key, Value> map = this.mapCopy;
use map

正如您所看到的,您永远不需要在读取时获得锁定,只能在写入时使用。

  

如果我降级了地图,那么长迭代器必须保持读锁定以避免并发访问异常。我认为这会长时间阻止写作线程。

而不是猜测,我建议你测量它。

  

我想知道是否有关于此的研究

如果有的话,我不会认真对待这样的研究。如你所知,结果会因你的情况而异。