shrini1000
shrini1000

Reputation: 7226

Java: practical usecases for serializing Singletons?

We keep reading about how to use 'readResolve()' to ensure singleness in case of serializing a Singleton. But what are practical use cases for wanting to serialize a Singleton in the first place?

EDIT: pl. note: the question is about why to serialize a Singleton, and not about what's a safe way to do so.

Upvotes: 4

Views: 680

Answers (3)

gustafc
gustafc

Reputation: 28865

The object may be a singleton, but it may be part of a larger structure which doesn't quite know it is. For example, it may implement an interface which can have several different implementations (and thus, instances):

interface StringSink extends Serializable { void dump(String s); }

class MultiDumper implements Serializable {
    private final StringSink sink;
    public MultiDumper(StringSink sink){ this.sink = sink; }
    void doSomeStuff(Collection<String> strings){
        for (String s : strings) sink.dump(s);
    }
}

Now, let's say we want a StringSink which dumps strings to stdout. Since there's only one stdout, we might as well make it a singleton:

/** Beware: Not good for serializing! */
class StdoutStringSink {
    public static final StdoutStringSink INSTANCE = new StdoutStringSink();
    private StdoutStringSink(){}
    @Override
    public void dump(String s){ System.out.println(s); }
}

And we use it like this:

MultiDumper dumper = new MultiDumper(StdoutStringSink.INSTANCE);

If you were to serialize, and then deserialize this dumper, you'd have two StdoutStringSink instances floating around in your program.

Upvotes: 1

mikera
mikera

Reputation: 106351

The most common case would be where you have an object representing a large data structure (e.g. a tree of nodes in a XML-style document).

This data structure could easily contain singleton values (e.g. singleton instances that represent the data type of a particular attribute attached to a node in the tree). Many different nodes in the tree could point to the same shared singleton value.

There are many circumstances where you might want to serialise such a data structure, e.g. sending a copy of the object over the network. In this case you would also need to serialise the singleton values.

But then when you read the data structure back in, you want to use the existing value of the singleton, not a newly created instance. This is why you need readResolve()

Upvotes: 4

Andrzej Jozwik
Andrzej Jozwik

Reputation: 14649

Joshua Bloch Effective Java (2nd Edition) suggest to use Enum as singleton. It is always created by VM and it is impossible (or hard) to create second instance of singleton.

For normal singleton you can always "hack" the system, see:

Singleton Pattern

Hot Spot:
Multithreading - A special care should be taken when singleton has to be used in a multithreading application.
Serialization - When Singletons are implementing Serializable interface they have to implement readResolve method in order to avoid having 2 different objects.
Classloaders - If the Singleton class is loaded by 2 different class loaders we'll have 2 different classes, one for each class loader. 
Global Access Point represented by the class name - The singleton instance is obtained using the class name. At the first view this is an easy way to access it, but it is not very flexible. If we need to replace the Sigleton class, all the references in the code should be changed accordinglly.

Upvotes: 2

Related Questions