【发布时间】:2014-01-17 04:29:03
【问题描述】:
我正在编写一个高度并发的应用程序,需要访问大量细粒度的共享资源。我目前正在编写一个全局锁管理器来组织它。我想知道我是否可以背负标准ConcurrentHashMap 并使用它来处理锁定?我正在考虑一个类似如下的系统:
- 单个全局
ConcurrentHashMap对象包含资源的唯一字符串 id 与保护该资源的锁使用该资源的线程的唯一 id 之间的映射 - 调整并发因子以反映对高并发性的需求
- 使用 hashmap 中的原子条件
replace(K key, V oldValue, V newValue)方法获取锁 - 为防止在锁定多个资源时发生锁争用,必须按字母顺序获取锁
设置是否存在任何重大问题?表现会如何?
我知道这可能会比一个正确编写的锁定系统慢得多,而且内存量更大,但我宁愿不花几天时间尝试编写自己的锁定系统,特别是考虑到我可能无法编写自己的锁定系统匹配 Java 专业编写的实现映射的并发代码。
另外,我从来没有在高负载情况下使用过 ConcurrentHashMap,所以我对以下内容感兴趣:
- 这对大量元素的扩展效果如何? (我认为 ~1,000,000 是一个不错的上限。如果超过这个上限,我愿意更有效地重写它)
- 文档指出,重新调整大小“相对”较慢。到底有多慢?我可能必须每分钟左右重新调整一次地图的大小。这会对我正在查看的地图大小造成问题吗?
编辑:感谢 Holger 指出 HashMaps 在缩放方面不应该有那么大的问题
另外,有没有更好/更标准的方法?我找不到任何使用这种系统的地方,所以我猜测要么我没有看到重大缺陷,要么还有其他问题。
编辑:
我正在编写的应用程序是一个网络服务,它处理可变数量的请求。我正在使用 Grizzly 项目来平衡多个线程之间的请求。 每个请求都使用少量的共享资源(~30),所以一般来说,我预计不会有很大的争用。请求通常在 500 毫秒内完成对资源的处理。因此,我会接受一些阻塞/连续轮询,因为请求不是对时间非常敏感,并且争用应该是最小的。
一般来说,看到正确的解决方案与 ConcurrentHashMap 在幕后的工作方式非常相似,我想知道我是否可以安全地使用它作为快捷方式,而不是编写/调试/测试我自己的版本。
【问题讨论】:
-
我刚刚在 Google Guava 中发现了
Striped,这就是我想要的一切。 -
条纹可能仍然是内存密集型。在这里查看我的旅程:stackoverflow.com/q/39675003/194609
标签: java multithreading concurrency locking concurrenthashmap