我有一个对象,其内部可变状态不断地被一个或多个线程更新。该对象是同步的,目标是从另一个线程定期保存其状态(通过序列化):
public class Counter implements Serializable {
private int dogCount;
private int catCount;
public synchronized void updateFromDogThread( int count ) {
dogCount = count;
}
public synchronized void updateFromCatThread( int count ) {
catCount = count;
}
}
问题:
- 在这种情况下序列化安全吗?
- 它是如何运作的?也就是说,
ObjectOutputStream
是否会阻塞执行序列化,直到没有线程再对Counter
进行操作? - 如果
Counter
的同步不使用内部锁,而是使用其他锁怎么办?
最佳答案
- Is serialization safe in this case?
没有。正如@Tom Hawtin 所说,您将需要执行自己的锁定以确保在序列化对象时不会更改对象。
- How does it work under the hood? That is to say, will the ObjectOutputStream performing the serialization block until no threads are any longer operating on Counter?
ObjectOutputStream
不在后台进行锁定。如果有必要,由应用程序执行此操作。
- What if Counter's synchronization doesn't use the intrinsic lock, but some other lock?
然后您的应用程序还需要使用其他锁来在序列化发生时锁定更新。
如果您正在序列化的状态仅由具有两个字段的一个对象的状态组成,那么锁争用和粒度应该不是问题。但是,如果对象很复杂,那么锁争用很可能会产生问题,就像在不冒死锁风险的情况下获取锁的问题一样。这种情况需要仔细设计。
关于 java 。多线程环境中对象的序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3077703/