HashMap和并发 – 不同的密钥

假设我有一个哈希映射和多个线程。 如果我有一个添加到哈希映射的同步方法,我怎么能让两个不同的线程可以同时(并发)将不同的键放入哈希映射?

我当前的实现是一个同步方法。 这会允许两个不同的线程同时将两个不同的键放入哈希映射中吗?

我使用的是常规哈希映射,而不是Java的并发哈希映射。 我不允许使用并发哈希映射。

编辑:我想我找到了解决方案! 我想我可能错误地写了这篇文章。 假设哈希映射被初始化为Integer作为其键,LinkedList作为其值。 为了放置一个全新的密钥,我意识到整个哈希映射必须同步(即锁定)。 但是,如果我试图将另一个String添加到已经包含的键的相应LinkedList中,我可以同步哈希映射的get方法。 我认为这将允许多个线程同时(并发)添加到不同的,已包含的键的LinkedLists。 如果我错了,请告诉我。

这是一个具体的例子。 我有一个哈希映射hashMap,它使用Integer作为键,LinkedList作为其值。 键5和10已经在哈希映射中。 键5包含Joey,Joe,Kerry的LinkedList。 键10包含Jerry,Mary,Tim的LinkedList。 我有两个线程t1和t2。 t1想要将Moe添加到与密钥5对应的LinkedList中.t2想要将Harry添加到与密钥10对应的LinkedList中。两者将同时添加到散列映射中,因为散列映射的值仅被锁定。

我当前的实现是一个同步方法。 这会允许两个不同的线程同时将两个不同的键放入哈希映射中吗?

不可以。只有ConcurrentHashMap或专门设计的并发映射才能安全地支持它,所以你不可能将两个键同时从两个线程放入同一个映射中。

我怎么能让两个不同的线程同时(并发地)将不同的键放入哈希映射?

如果不使用ConcurrentHashMap ,则不能使用另一个ConcurrentMap实现,也不能实现自己的实现。

最简单的答案是使用ConcurrentHashMap ,它完全符合您的要求。

如果你不能这样做(我看到你在回答之后编辑了你的post),那么你将不得不复制ConcurrentHashMap所做的事情。 不,简单地同步HashMap的方法将不允许两个线程同时添加键值对,他们必须等待并一次一个。

你的问题的答案是否定的。 因为同步块强制每个胎面在单个队列中等待。 使用ConcurrentHashMap您有更多机会同时添加,因为它只锁定要插入元素的篮子,而不是锁定整个HashMap。

但是,如果我试图将另一个String添加到已经包含的键的相应LinkedList中,我可以同步哈希映射的get方法。 我认为这将允许多个线程同时(并发)添加到不同的,已包含的键的LinkedLists。

HashMap只读访问是安全的:您可以让多个线程调用get方法,完全没有同步,没有任何中断。 如果链接之间没有共享链接列表,则您也不需要同步。 为了确保线程永远不共享列表,映射键应该是线程特定的东西,如本地创建的对象或线程ID。

什么是不安全的是让另一个线程与读或写同时修改映射或列表。 这是读写锁的用例:它允许多个并发读取,但写入必须是独占的。