[英]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
不可变并使用ConcurrentHashMap
的compute()
方法来更新值,但现在的问题是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.