How to navigate the deceptively simple Singleton pattern

The Singleton pattern is deceptively simple, even and especially for Java developers. In this classic JavaWorld article, David Geary demonstrates how Java developers implement singletons, with code examples for multithreading, classloaders, and serialization. He concludes with a look at implementing singleton registries in order to specify singletons at runtime.

1 2 3 Page 3
Page 3 of 3

Example 13. Test a serializable singleton

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 = 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);
   }
   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(NotSerializableException se) {
         logger.fatal("Not Serializable Exception: " + se.getMessage());
      }
      catch(IOException iox) {
         logger.fatal("IO Exception: " + iox.getMessage());
      }
   }
   private Singleton readSingleton() {
      Singleton s = null;
      try {
         FileInputStream fis = new FileInputStream("serializedSingleton");
         ObjectInputStream ois = new ObjectInputStream(fis);
         s = (Singleton)ois.readObject();
      }
      catch(ClassNotFoundException cnf) {
         logger.fatal("Class Not Found Exception: " + cnf.getMessage());
      }
      catch(NotSerializableException se) {
         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 for equality");
      Assert.assertEquals(true, sone == stwo);
   }
}

The preceeding test case serializes Example 12's singleton and deserializes it twice. Then the test case checks to see if the deserialized singletons are the same object. Here's the test case output:

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 for equality
     [java] Time: 0.1
     [java] OK (2 tests)

Singleton sign-off

The Singleton pattern is deceivingly simple, especially for Java developers. In this article, I've demonstrated how Java developers implement singletons, considering multithreading, classloaders, and serialization. I've also shown how you can implement singleton registries that let you specify singleton classes at runtime.

David Geary is the author of Core JSTL Mastering the JSP Standard Tag Library (Prentice Hall, 2002; ISBN: 0131001531), Advanced JavaServer Pages (Prentice Hall, 2001; ISBN: 0130307041), and the Graphic Java series (Prentice Hall). David has been developing object-oriented software with numerous object-oriented languages for 18 years. Since the GOF Design Patterns book was published in 1994, David has been an active proponent of design patterns, and has used and implemented design patterns in Smalltalk, C++, and Java. In 1997, David began working full-time as an author and occasional speaker and consultant. David is a member of the expert groups defining the JSP Standard Tag Library and JavaServer Faces, and is a contributor to the Apache Struts JSP framework.

Learn more about this topic

1 2 3 Page 3
Page 3 of 3