ConcurrentMap条目同步而不阻止整个映射

时间:2017-08-21 15:07:00

标签: java multithreading

休息服务有许多彼此无关的客户。 每个客户都可以随时开始投票。 一旦客户增加了第一次投票,我就会在

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

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

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

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

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

我觉得我正在尝试解决已经解决的问题,并且有一个完美的API和良好的方法,但我无法做出正确的谷歌请求。你能提出一些提示吗?我使用Java8和Spring。

1 个答案:

答案 0 :(得分:5)

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

我可以看到的主要危险是,如果您的投票到期流程从votesByCustomer删除了客户条目,那么您可能会在竞争条件下结束您对不再与之关联的ConcurrentHashMap的投票顾客。因此,即使是投票已全部到期的客户,也必须确保在其中留空ConcurrentMap