java - 如何在 Java 中执行键值映射的线程安全时间点快照?

标签 java serialization concurrency

在我的应用程序中,我有一个键值映射,用作存储数据的中央存储库,用于在崩溃或重启(检查点)后返回到定义的状态。

该应用程序是多线程的,多个线程可能会将键值对放入该映射中。一个线程负责定期创建一个检查点,i。 e.将映射序列化到持久存储。

在写入检查点时, map 应保持不变。避免添加新项目相当容易,但是其他线程如何更改 map 中“它们的”对象的成员呢?

我可以有一个对象,它的监视器在检查点开始时被占用,并将对映射的任何成员及其成员的所有写访问包装在与该对象同步的 block 中。这对我来说似乎非常容易出错且乏味。

我还可以将 map 设为检查点专用,并且只将提交对象的副本放入其中。但是我必须确保副本是深拷贝,并且我无法让 map 中的数据自动更新,每次对提交的对象进行更改时,提交者都必须重新提交它们。这看起来开销很大,而且容易出错,因为我必须记住将重新提交代码放在所有正确的位置。

解决这个问题的优雅可靠的方法是什么?

最佳答案

what about other threads changing members of "their" objects inside the map

这里有一个问题 :) 并且无法通过任何类型的 Map 解决...

一种解决方案是在您的 map 中只允许不可变对象(immutable对象),但这对您来说可能是不可能的。

否则,您必须为所有可能更改您的 map 引用的数据的线程共享一个锁,并在您的快照期间将它们全部阻塞;但这是一个停止世界的方法......

关于java - 如何在 Java 中执行键值映射的线程安全时间点快照?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/665592/

相关文章:

java - 为什么 Java 编译器在构造函数实例化中会丢失对泛型类型的跟踪?

java - Mockito Java doAnswer

java - Java 中的赋值运算符

java - 将 getTime() 的值转换为毫秒时出错

c# - 使用 Json.net 序列化时如何更改属性名称?

c# - 使用 WCF 和 Data Contract Serializer 时需要生成 XmlSerializers 程序集

java - 用java序列化员工列表

Golang并发,批量处理元素

Spring框架MVC "concurrency"?

c++ - 为什么 sleep() 会阻塞 std::ostream