并发哈希映射中值的原子更新 - 如何?
Atomic updates of values in concurrent hash map - how to?
任务是跟踪一些 运行 进程。将该信息保存在内存中就可以了,所以我使用并发哈希映射来存储该数据:
ConcurrentHashMap<String, ProcessMetaData> RUNNING_PROCESSES = new ConcurrentHashMap();
将新对象安全地放入地图中一切都很好,问题是这些进程的状态会发生变化,因此我必须不时更新 ProcessMetaData
。我使 ProcessMetaData
不可变并使用 ConcurrentHashMap
的 compute()
方法来更新值,但现在问题是 ProcessMetaData
变得更加复杂并且保持不可变变得难以管理。问题是 - 只要我只更新 ProcessMetaData
原子(根据 javadoc)compute()
方法 - 对象可能是可变的并且整体事物仍然是线程安全的?我的假设正确吗?
只要您只访问传递给 compute
的函数中的值,在该函数中所做的修改是安全的。
然而,这是一个毫无意义的理论观点。将值存储到集合或映射中的目的是最终检索和使用它们。这就是问题开始的地方。
compute
方法returns结果值就像get
returns当前存储的值。一旦调用者开始使用该值,此使用可能与地图上的后续 compute
操作并发。 get
方法甚至可以在 compute
操作正在进行时检索值。允许 非阻塞 检索操作是 ConcurrentHashMap
的主要特征之一。因此,可能会出现各种竞争条件。
因此,只有当您将映射用作只写内存时,使用可变对象并修改已存储在 compute
中的值才是安全的,这是一个牵强附会的场景。当您使用不同的线程安全机制来确保在开始读取地图之前已完成所有更新时,它可能会起作用,但您的用例似乎有所不同。
任务是跟踪一些 运行 进程。将该信息保存在内存中就可以了,所以我使用并发哈希映射来存储该数据:
ConcurrentHashMap<String, ProcessMetaData> RUNNING_PROCESSES = new ConcurrentHashMap();
将新对象安全地放入地图中一切都很好,问题是这些进程的状态会发生变化,因此我必须不时更新 ProcessMetaData
。我使 ProcessMetaData
不可变并使用 ConcurrentHashMap
的 compute()
方法来更新值,但现在问题是 ProcessMetaData
变得更加复杂并且保持不可变变得难以管理。问题是 - 只要我只更新 ProcessMetaData
原子(根据 javadoc)compute()
方法 - 对象可能是可变的并且整体事物仍然是线程安全的?我的假设正确吗?
只要您只访问传递给 compute
的函数中的值,在该函数中所做的修改是安全的。
然而,这是一个毫无意义的理论观点。将值存储到集合或映射中的目的是最终检索和使用它们。这就是问题开始的地方。
compute
方法returns结果值就像get
returns当前存储的值。一旦调用者开始使用该值,此使用可能与地图上的后续 compute
操作并发。 get
方法甚至可以在 compute
操作正在进行时检索值。允许 非阻塞 检索操作是 ConcurrentHashMap
的主要特征之一。因此,可能会出现各种竞争条件。
因此,只有当您将映射用作只写内存时,使用可变对象并修改已存储在 compute
中的值才是安全的,这是一个牵强附会的场景。当您使用不同的线程安全机制来确保在开始读取地图之前已完成所有更新时,它可能会起作用,但您的用例似乎有所不同。