简体   繁体   English

并发 hash map 中值的原子更新 - 如何?

[英]Atomic updates of values in concurrent hash map - how to?

Task is to keep track of some running processes.任务是跟踪一些正在运行的进程。 Keeping that information in memory is just fine, so I'm using a concurrent hash map to store that data:将这些信息保存在 memory 中就可以了,所以我使用并发的 hash map 来存储该数据:

ConcurrentHashMap<String, ProcessMetaData> RUNNING_PROCESSES = new ConcurrentHashMap();

It's all good and fine with safely putting new objects in the map, problem is that state of those processes change so I have to update ProcessMetaData from time to time.安全地将新对象放入 map 一切都很好,问题是这些进程的 state 发生了变化,所以我必须不时更新ProcessMetaData I made ProcessMetaData immutable and use ConcurrentHashMap 's compute() method to update values, but now the problem is ProcessMetaData gets more complicated and keeping it immutable gets hardly manageable.我使ProcessMetaData不可变并使用ConcurrentHashMapcompute()方法来更新值,但现在的问题是ProcessMetaData变得更加复杂,并且保持它不可变变得难以管理。 The question is - as long as I only update ProcessMetaData in atomic (as per javadoc) compute() method - the object may be mutable and overall things will still be thread-safe?问题是——只要我只在原子(根据 javadoc) compute()方法中更新ProcessMetaData ——object 可能是可变的并且总体上仍然是线程安全的? Is my assumption correct?我的假设正确吗?

As long as you only access the value within the function passed to compute , modifications made in that function are safe.只要您只访问传递给compute的 function 中的值,在 function 中进行的修改是安全的。

This, however, is a pointless theoretical view.然而,这是一种毫无意义的理论观点。 The purpose of storing values into a collection or map, is to eventually retrieve and use them.将值存储到集合或 map 的目的是最终检索和使用它们。 And this is where the problems start.这就是问题开始的地方。

The compute method returns the result value just like get returns the currently stored value. compute方法返回结果值,就像get返回当前存储的值一样。 Once a caller starts using that value, this use may be concurrent to subsequent compute operations on the map.一旦调用者开始使用该值,此使用可能与 map 上的后续compute操作并发。 The get method may even retrieve the value while a compute operation is in progress. get方法甚至可以在compute操作正在进行时检索该值。 Allowing non-blocking retrieval operation is one of ConcurrentHashMap 's main features.允许非阻塞检索操作是ConcurrentHashMap的主要功能之一。 Therefore, all kind of race conditions may occur.因此,可能会出现各种竞态条件。

So, using a mutable object and modifying an already stored value in compute is only safe, when you use the map as write-only memory, which is a far-fetched scenario.因此,当您将 map 用作只写 memory 时,使用可变 object 并修改compute中已存储的值是安全的,这是一个牵强的方案。 It might work when you use a different thread safe mechanism to ensure that all updates have been completed before starting to read the map, but your use case seems to be different.当您使用不同的线程安全机制以确保在开始读取 map 之前已完成所有更新时,它可能会起作用,但您的用例似乎有所不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM