【问题标题】:Different users select same key in java hashmap at same time --- will it be thread safe?不同的用户同时在 java hashmap 中选择相同的键 --- 它是线程安全的吗?
【发布时间】:2014-04-07 05:55:37
【问题描述】:

我有一个在 java 中工作的函数,这样 HashMap 将键存储为 String,值存储为 ArrayList。所以我的问题是当不同的用户同时登录并且他们尝试访问 web 应用程序并会选择相同的密钥时,比在这种情况下需要同步 hashmap 吗?

like ..当 User1 登录时,hashmap 中的 vlaue 将存储在幕后,例如 map.put(A, List1) map.put(B, List2)

当 User2 登录时,hashmap 中的 vlaue 将存储在幕后,例如 map.put(A, List3) map.put(C, List4)

所以现在如果两个用户将同时登录并且密钥相同但(列表值总是不同)比这个哈希图需要同步??。

【问题讨论】:

标签: java collections


【解决方案1】:

无论您是否使用相同的密钥,HashMap 对于任何写作都不是线程安全的:

请注意,此实现不同步。如果多个线程同时访问一个哈希映射,并且至少有一个线程在结构上修改了映射,则它必须在外部同步。 (结构修改是添加或删除一个或多个映射的任何操作;仅更改与实例已包含的键关联的值不是结构修改。)

即使涉及不同的键,同时两个操作都可能触发内部映射扩展,从而导致问题。 (或者即使有一个写操作和一个读操作,如果写操作添加或删除一个键,那可能会抛出读操作。)

选项:

编辑:如果事实上你没有有多个线程同时修改地图(因为你每个用户有一个地图),那么大部分问题都会消失......尽管如果仍然可能有多个线程访问映射(只是不是同时)我很想使用并发映射无论如何以避免过时读取等问题。

【讨论】:

  • 但我认为共享资源时应该使用同步集合。所以,如果我对不同的用户总是有不同的键值..还需要同步吗?
  • @gSingh:您的 map 是共享资源。正如我所说,它们是不同的密钥这一事实并不能保证安全。如果在您开始之前在映射中分配了所有键,那么不会有任何结构修改,您可能会没事......但我可能只使用ConcurrentHashMap
  • @gSingh 您最好的选择可能是根本不使用地图,并将需要存储的内容存储在数据库中。如果您希望将内存状态绑定到特定用户,请使用 HttpSession。这就是它的用途。
  • @jon 感谢您清除这个......请也清除这个......实际上,一旦用户登录,我就会将该用户的所有值存储在地图中,而不是将该地图放入会话中在进一步的页面中,用户将修改该地图。因此,即使我将该地图放入用户的会话中,同时另一个用户登录——在这种情况下,我还需要使用 ConcurrentHashMap 吗?
  • @gSingh:是的。因为您仍在使用多个线程,并且其中至少一个线程可能正在进行结构更改。请参阅我在回答前面引用的文档。
【解决方案2】:

你的问题不是很清楚。但是,一旦多个线程访问一个非线程安全的集合,并且其中至少有一个线程写入该集合,那么您需要适当的同步,并且 所有 对映射的访问必须同步。

【讨论】:

    【解决方案3】:

    同意 Jon Skeet "如果涉及不同的key,两个操作同时会触发内部map扩展,导致问题"

    但是可能有特定的场景,因为“HashMap 仅在应用程序开始时填充数据库连接参数等数据,然后我们只从中获取数据”然后为每个线程选择操作将返回相同的值。

    在 Jon Skeet 提到的所有其他场景中,您有以下选项 1) 使用同步集合(例如 Collections.synchronizedMap) 2) 使用并发集合(例如 ConcurrentHashMap) 3)自己同步所有访问

    【讨论】:

    • @shirsih 谢谢!我将再次使用这些选项......当我会使用说 ConcurrentHashMap 并在其中存储 List 值而不是那些 List 值也需要同步?还是 ConcurrentHashMap 会解决这个问题?
    • ConcurrentHashMap请参考docs.oracle.com/javase/7/docs/api/java/util/concurrent/…。据我了解,concurrentHashMap 已在 HashMap 上同步更新操作,但该 Map 中的值仍然可以被许多线程访问。在这里,当您使用 List 时,我认为您也应该同步列表。
    猜你喜欢
    • 2011-02-10
    • 1970-01-01
    • 2012-05-09
    • 1970-01-01
    • 2012-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多