线程安全哈希映射?

我正在编写一个应用程序,它将向用户返回HashMap。用户将获得对此 MAP 的引用。在后端,我将运行一些将更新Map的线程。

到目前为止,我做了什么?


我已经制作了所有后端线程,因此共享一个公共通道来更新MAP。因此,在后端,我确信并发写入操作不会成为问题。


我遇到的问题


  1. 如果用户尝试更新 MAP,同时在后端更新 MAP -->并发写入操作问题。
  2. 如果使用尝试从 MAP 读取某些内容,同时在后端更新 MAP -->并发读写操作问题。

直到现在我还没有遇到过这样的问题,但我担心我将来可能会面临。请给出建议。

我正在使用ConcurrentHashMap<String, String>.


答案 1

使用 ConcurrentHashMap,您正走在正确的轨道上。对于每个点:

  1. 查看 putIfAbsentreplace 两者都是线程安全的,并且结合了检查哈希映射的当前状态并将其更新为一个原子操作的方法。
  2. get 方法不会在内部同步,但将返回其可用的指定键的最新值(检查 ConcurrentHashMap 类 Javadoc 进行讨论)。

Collections.synchronizedMap 相比,它的好处是组合方法,它们以内部同步的方式提供传统的 Map 和逻辑。使用这些方法,不要尝试提供自己的自定义同步,因为它不起作用。集合在内部同步,其他线程不会响应同步对象的尝试(例如 不会阻塞其他线程)。ConcurrentHashMapputIfAbsentgetputConcurrentHashMapjava.util.concurrentsynchronize(myConcurrentHashMap){}


答案 2

附注:

你可能想看看Cliff Click的无锁哈希表实现,它是高度可伸缩的Java库的一部分。

(这是Cliff Click的Google Talk,关于这个锁免费哈希。