两个线程,其中一个线程对某个实例进行功能新操作,另一个线程将同一个实例序列化后通过网络发送。如何保证线程安全。
----------------------------------------------------------------------------------------
网上这方面的资料只有寥寥几篇。
先贴上这个靠谱点的
private int dogCount;
private int catCount;
public synchronized void updateFromDogThread( int count ) {
dogCount = count;
}
public synchronized void updateFromCatThread( int count ) {
catCount = count;
}
}
- Is serialization safe in this case?
- 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?
- What if Counter's synchronization doesn't use the intrinsic lock, but some other lock?
- Is serialization safe in this case?
- 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?
- What if Counter's synchronization doesn't use the intrinsic lock, but some other lock?
synchronized (counter) {As you noticed, the object locked is arbitrary, so how would the serialisation mechnaism know how to obtain the relevant lock. Worse than that, the order of serialising and object graph is also quite arbitrary, so any attempt to lock would often lead to deadlocks. Even with the solution above, you are performing a complex operation within a lock, so be careful about deadlocks.
out.writeObject(counter);
}
下面贴几个不大靠谱的
这个不大明白啥意思
By synchronizing both the methods which serialize and modify the object state.
-----------------------------------------------------------------------
final int age;
final String name;
final String address;
MyClass(int age, String name, String address) {...}
MyClass setNameAndAddress(String name, String address) {return new MyClass(age, name, address);}
}
又是一个不靠谱的
I know the Vector class is thread-safe for adding and removing elements [reference].
If I serialize a Vector using an ObjectOutputStream am I guaranteed a consistent (and non-corrupt) state when I deserialize it even if other threads are adding and removing objects during the seralization?
The writeObject() method is synchronized. But there's nothing in the Javadoc that guarantees that unless it's implied by the statement 'Vector is synchronized'.
Note that the readObject() method doesn't need to be synchronized, as the object isn't accessible to anybody until readObject() returns.
***************************************************************************************************************
****************************************************************************************************************
《Effective Java中文版第2版》P264:
无论你是否使用默认的序列化形式,如果在读取整个对象状态的任何其他方法上强制任何同步,则也必须在对象序列化上强制这种同步。因此,如果你有一个线程安全的对象,它通过同步每个方法实现了它的线程安全,并且你选择使用默认的序列化形式,就要使用下列的writeObject方法:
private synchronized void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
}
如果你把同步放在writeObject方法中,就必须确保它遵守与其他动作相同的锁排列(lock-ordering)约束条件,否则就有遭遇资源排列(resource-ordering)死锁的危险【Goetz06,10.1.5】。
------------------------------------
至于readObject,书中没提, 我想应该不需要同步,原因正是因为书中反复提到的一句话:readObject方法实际上相当于另一个公有的构造器,如同其他的构造器一样。...不严格地说,readObject是一个“用字节流作为唯一参数”的构造器。嗯,上面提到的这句话还是有点道理的:
傲轩游戏网