【问题标题】:JSF ApplicationScoped HashMap - ConcurrentHashMapJSF ApplicationScoped HashMap - ConcurrentHashMap
【发布时间】:2015-03-15 12:26:56
【问题描述】:

在应用程序范围的 bean 中,我们有一个 hashmap,它为每个用户保存一些计数器(只是暂时的,没有保存在任何地方)每个用户都由它自己的子 hashmap 表示:

Map<String, Map<String, Object>> userValues = new HashMap<String, Map<String, Object>>();

例如:

application.getUserValues().get(user.id).put("lastAction", new Date());

每个 Sub-Hash-Map 在启动期间都被初始化为空(单线程)。每个 Sub-Hash-Map 保证只能被修改(“放置”,从不删除)并且不会被替换。

Sub-Hash-Maps 上的写访问保证在任何时候都只能由单个线程进行,但如上例所示,可能有 2 个线程同时修改两个不同的 sub-maps)

我们没有使用 SessionScope,因为一些信息也需要暴露给其他会话(即 Teamlead 应该能够看到这些值)

到目前为止,从来没有并发问题,但是并发总是很难正确“测试”,因为它主要取决于整个系统负载和大约同时执行的操作。

关注此线程:Is ConcurrentHashMap.get() guaranteed to see a previous ConcurrentHashMap.put() by different thread? 我假设,将并发哈希映射用于内部哈希映射将完全确保在同一映射上同时从不同线程使用 putget 没有问题。

所以用Map&lt;String, ConcurrentHashMap&lt;String, Object&gt;&gt;会更好吧?

是否还需要为“外部”映射使用 ConcurrentHashmap?该地图永远不会改变,只有对该地图的操作将是get()

【问题讨论】:

    标签: java multithreading


    【解决方案1】:

    如果您的同一个子图被多个线程访问,并且它们也写入该图,那么 ConcurrentHashMap 是有意义的。如果他们只是在最初写入一次时读取数据,甚至在多个线程开始说初始化之前,例如,那么你不需要 concurrentHashMap。

    同样,您也需要考虑外部地图。

    【讨论】:

    • 确保对子图的写入是独占的。然而,另一个线程可以在同一张地图上读取。即application.getUserValues().get("47fjkgfg4").put("lastAction", new Date());application.getUserValues().get("47fjkgfg4").get("lastAction); 可以同时出现在不同的线程中。
    • 是的,那么我建议你使用 ConcurrentHashMap。
    • 非常感谢。假设也是如此。但是对于外部的,在任何时候只执行get,我就不用说了吗?
    • 肯定。如果您只初始化一次并且有多个阅读器,那么您就不必考虑线程。
    猜你喜欢
    • 2012-05-08
    • 2010-11-25
    • 2010-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-02
    • 1970-01-01
    相关资源
    最近更新 更多