如果您使用Java序列化对象并将其(通过套接字)发送到群集中的节点,您是否自动获得线程安全性?
假设您有一个群集,每个节点都有几个核心。服务器有一个Java对象,它希望将其发送到每个要处理的集群上的每个核心。它序列化该对象并将其发送给每个接收者。
通过序列化,该对象是否会自动“深度复制”并且您是否自动获得该对象的线程安全性?您不会在群集上的各个节点之间遇到任何并发问题,因为它们无法访问内存中的相同位置......但是节点上的核心之间又如何呢?
答案 0 :(得分:4)
序列化操作不是线程安全的,并且对正在修改的对象进行序列化不是一个好主意。但是,对象的任何深层副本,在同一个线程,进程或Universe中都是完整副本,并且在更改原始文件时不会更改。
注意:如果再次发送更新的对象,则可能看不到更新,因为它只是发送对该对象的引用。因此,如果要发送更新,则应在发件人上调用reset()
。使用reset()
的另一个原因是避免“内存泄漏”,因为发送方和接收方将记住他们写过/读过的每个对象。
答案 1 :(得分:3)
通过序列化,该对象是否会自动“深度复制”并且您是否自动获得该对象的线程安全性?
目前尚不清楚你的意思,但......
序列化过程不是线程安全的。例如,如果一个线程序列化一个对象而另一个线程正在更改它,则序列化对象(即字节序列)可能不代表该对象的一致快照。
一旦序列化,通常无法访问可能会弄乱它的字符序列,因此线程安全不是问题。
当反序列化字节序列时,您将获得全新的对象。除非反序列化它们的线程也将它们发布到其他线程,否则这些对象不存在线程安全问题。
您不会在群集上的各个节点之间遇到任何并发问题,因为它们无法访问内存中的相同位置......但是节点上的核心之间会有什么问题?
对象是否在与序列化相同的地址空间中反序列化没有区别。反序列化创建 new 对象。它们是原始对象的副本。
答案 2 :(得分:1)
绝对是"线程安全" (在你定义它的意义上)。根据定义,序列化是对象的深层副本,每个工作者将获得不同的对象。