views:

70

answers:

3

This is a followup question to: http://stackoverflow.com/questions/3077703/java-serialization-of-objects-in-a-multithreaded-environment.

Suppose I have a collection of objects that are always acted upon by multiple threads.

public class AlwaysChanging implements Serializable {
    // ... state ...

    public synchronized void updateFromThread1( int data ) { /* ... */ }
    public synchronized void updateFromThread2( int data ) { /* ... */ }

}

What is a safe way to serialize a Collection<AlwaysChanging>?

+2  A: 

First of all, why do you have different update methods for different threads? This seems messy and inextensible.

To serialize the collection, you need to make sure that none of your AlwaysChanging are changing during serialization. From this design, it seems the only way to do that would be to hold all of their locks prior to serialization. Alternatively, you could make a deep copy of the entire collection (copy all of the objects) and serialize that.

Without knowing much about the rest of your application, I'd recommend looking into ReadWriteLock as a more finely-grained locking solution.

danben
`ReadWriteLock` wont help much if the access pattern is mostly-write, as appears here.
Tom Hawtin - tackline
There are multiple data sources which push data from different threads via an interface (they are not actually called `updateFromThreadX` :-). Each `AlwaysChanging` object is a subscriber of these data sources, and is subject to manipulation by multiple threads at once. `AlwaysChanging` is inherently event driven; the only other design consideration might be to queue-ize the incoming data (but this might not be possible and this does not solve the serialization problem).
Jake
A: 

The only safe way is to make the collection read-only while serializing it.

The synchronized mechanism will not work as you cannot easily run a method call on all objects (to some synchronized blockWhileSynchronizing() method) and THEN do the serialization.

It may be easier to rewrite your synchronized methods into submitting entries in an Executor as this allows you to control the mechanism actually doing the execution.

Thorbjørn Ravn Andersen
A: 

Are the default synchronization methods sufficient? Since your update methods are synchronized, why not just override the default serialization mechanism with synchronization?

 private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
      lock(this) {
        ois.defaultReadObject();
      }
    }

  private void writeObject(ObjectOutputStream oos) throws ClassNotFoundException, IOException {
      lock(this) {
        oos.defaultWriteObject();
      }
    }
John D