【问题标题】:ConcurrentMap entries synchronization without blocking whole mapConcurrentMap 条目同步而不阻塞整个地图
【发布时间】:2017-08-21 15:06:59
【问题描述】:

Rest service 有很多互不相关的客户。 每个客户都可以随时开始投票过程。 一旦客户添加第一票,我就会在

中创建一个条目
ConcurrentMap<customerId, ConcurrentMap<voteId, voteTimestamp>> votesByCustomer;

每个投票都有 voteTimestamp,所以当它过期时 - 它被另一个线程从地图中删除。 (此删除不是简单的votesByCustomer.remove() 调用,它涉及对votesByCustomer 映射的多个后续调用,因此必须另外同步)。 因此,上面的votesByCustomer 地图在所有客户之间共享。 (作为枚举支持的单例中的字段实现)。

此映射有许多操作,其中涉及对votesByCustomer 的多次调用以原子方式完成。所以我使用syncronized(votesByCustomer) {} 表达式。

因此,当调用这些方法时,它会锁定所有客户。

我的问题是我如何以这种方式编写代码,这样当我为一个客户进行操作时,它看起来不像其他客户。

我觉得我正在尝试解决一个已经解决的问题,并且有一个完美的 API 和好的方法来解决这个问题,但我真的无法提出正确的 google 请求。请给点建议好吗?我使用 Java8 和 Spring。

【问题讨论】:

    标签: java multithreading


    【解决方案1】:

    也许您可以使用computeIfAbsent() 安全快速地获取与该客户关联的特定ConcurrentMap(或者如果不存在则创建一个新的),然后在该客户特定ConcurrentMap 上使用synchronized 块用于特定于该客户的所有操作。

    我可以看到的主要危险是,如果您的投票过期过程曾经从 votesByCustomer 中删除客户条目,那么您最终可能会陷入竞争状态,您将投票记录到不再与该客户关联的 ConcurrentHashMap。因此,您必须确保在其中留下一个空的ConcurrentMap,即使对于投票已全部过期的客户也是如此。

    【讨论】:

      猜你喜欢
      • 2011-10-21
      • 2020-08-18
      • 2018-04-06
      • 1970-01-01
      • 2023-03-14
      • 2013-07-20
      • 1970-01-01
      • 2013-05-07
      相关资源
      最近更新 更多