If you serialize a singleton class and refactor it twice, you will get two instances of that Singleton class unless you implement the readresolve () method, as shown below:
Example 1: A serializable Singleton class
Java code
Import
Org. Apache. log4j. Logger;
Public class Singleton implements java. Io. serializable
{
Public static Singleton
Instance = new
Singleton ();
Protected Singleton ()
{
// Exists only to things
Instantiation.
}
Private object readresolve ()
{
Return
Instance;
}
}
The Singleton class implementation above returns a unique instance from the readresolve () method, so that no matter when the singleton class is restructured, it will only return the same Singleton class instance.
Example 2 test the singleton class of Example 1
Example 2 test a serializable Singleton class
Java code
Import
Java. Io .*;
Import
Org. Apache. log4j. Logger;
Import
JUnit. Framework. Assert;
Import
JUnit. Framework. testcase;
Public class singletontest extends testcase
{
Private Singleton sone = NULL,
Stwo =
NULL;
Private Static logger =
Logger. getrootlogger ();
Public singletontest (string
Name ){
Super (name );
}
Public void setup ()
{
Sone =
Singleton. instance;
Stwo =
Singleton. instance;
}
Public void
Testserialize ()
{
Logger.info ("testing Singleton
Serialization ...");
Writesingleton ();
Singleton S1 =
Readsingleton ();
Singleton S2 =
Readsingleton ();
Assert. assertequals (true, S1 =
S2); [/B]
}
Private void
Writesingleton ()
{
Try {
Fileoutputstream Fos = new
Fileoutputstream ("serializedsingleton ");
Objectoutputstream OOS = new
Objectoutputstream (FOS );
Singleton S =
Singleton. instance;
Oos. writeobject (singleton. instance );
Oos. Flush ();
} Catch (notserializableexceptionSe)
{
Logger. Fatal ("not serializable exception:" +
Se. getmessage ());
} Catch (ioexception iox)
{
Logger. Fatal ("Io exception:" +
Iox. getmessage ());
}
}
Private Singleton
Readsingleton ()
{
Singleton S =
NULL;
Try {
Fileinputstream FCM = new
Fileinputstream ("serializedsingleton ");
Objectinputstream OIS = new
Objectinputstream (FCM );
S =
(Singleton) Ois. readobject ();
} Catch (classnotfoundexception CNF)
{
Logger. Fatal ("class not found exception:" +
CNF. getmessage ());
} Catch (notserializableexceptionSe)
{
Logger. Fatal ("not serializable exception:" +
Se. getmessage ());
} Catch (ioexception iox)
{
Logger. Fatal ("Io exception:" +
Iox. getmessage ());
}
Return
S;
}
Public void
Testunique ()
{
Logger.info ("testing Singleton
Uniqueness ...");
Singleton another = new
Singleton ();
Logger.info ("Checking singletons
Equality ");
Assert. assertequals (true, sone =
Stwo );
}
}
Serialization Example 1 in the previous test case
And refactor it twice. Then, this test case checks whether the singleton instance to be restructured is the same object. The following is the output of the test case:
Java code
Buildfile:
Build. xml
Init:
[Echo] Build 20030422 (22-04-2003
11: 32)
Compile:
Run-test-text:
[Java]. info main: Testing Singleton
Serialization...
[Java]. info main: Testing Singleton
Uniqueness...
[Java] info main: Checking singletons
Equality
[Java] Time:
0.1
[Java] OK (2
Tests)
Singleton mode conclusion
The Singleton mode is simple but confusing, especially for Java developers. In this article, the author demonstrates how Java developers can implement the singleton mode in consideration of multithreading, class loaders, and serialization. The author also shows how you can implement the registry of a singleton class so that you can refer to the order class at run time.