3 Replies Latest reply: Nov 5, 2010 4:05 AM by 800330 RSS

    Query regarding Singleton Instance

    843853
      Hi,

      I have a query related to Singleton pattern implementation in Java.

      If I implement singleton design pattern, the singleton instance which Iam creating is per class/per JVM?

      I created a Singleton class and made the public method which returns instance as synchronized and Iam trying to access that singleton class from two different claases, Iam getting two instances of singleton. Please help me.

      Sample Code
      ==========

      This is Singleton Class
      ----------------------------------
      package com.test;

      import java.io.ObjectStreamException;
      import java.io.Serializable;

      public class Singleton implements Serializable
      {
      private static Singleton st=null;

      static int val=0;

      private Singleton()
      {  System.out.println("In constructor"); }

      public static synchronized Singleton stfactory()
      {
           System.out.println("In GetInstance");
           System.out.println("Static Value :" + val++);
           if(st==null)
           {
           st = new Singleton();
                System.out.println("Creating Instance");
                return st;
                
           }else
                return st;
           
      }
      public Object clone()
           throws CloneNotSupportedException
      {
      throw new CloneNotSupportedException();
      }

      }

      Created one JDKTimer componet, wihch acts as a scheduler.
      package com.test;


      import java.util.Timer;
      import java.util.TimerTask;

      public class TestSingleton extends TimerTask
      {
           @Override
           public void run() {
                     System.out.println("Singleton Object Created:" + Singleton.stfactory());
           }
      }

      This class is for starting the scheduler
      ============================
      package com.test;
      import java.util.Timer;
      import java.util.TimerTask;

      public class RunSingletonTest {

           public static void main( String[] args )
           {
                     System.out.println("In Runtest1");
                TimerTask task = new TestSingleton();
                Timer timer = new Timer();
                timer.schedule(task, 1000,10000);
           
           }
      }

      If the run the above class two times, Iam getting two instances of Singleton.

      -Giri.
        • 1. Re: Query regarding Singleton Instance
          jschellSomeoneStoleMyAlias
          sy.giri wrote:
          If the run the above class two times, Iam getting two instances of Singleton.
          That isn't how singletons work - in any language.

          It only works if you run it once.
          • 2. Re: Query regarding Singleton Instance
            800387
            Please use the 'code' button to format your code when posting.

            I'm not sure why you bothered to write a clone() method when the class itself does not implement Cloneable.

            I have no idea why you made the singleton Serializable. Unless you override readResolve() to return the instance itself, it is completely possible to make multiple "singletons" via serialization and deserialization .

            You did make the constructor private, which is good. However, why are you lazily creating this singleton? It would be far better to simply do:
            private static final Singleton INSTANCE = new Singleton();
            
            public static final Singleton getInstance() { 
                return INSTANCE; 
            }
            Now, I don't have to worry about a race condition or the inefficiency of using a synchronized block.

            - Saish
            • 3. Re: Query regarding Singleton Instance
              800330
              Having read about the holder-idiom somewhere once, I feel the need to add it for future reference while the thread is pretty old already:
              public class Singleton {
                // Private constructor prevents instantiation from other classes
                private Singleton() {}
               
                /**
                 * SingletonHolder is loaded on the first execution of Singleton.getInstance() 
                 * or the first access to SingletonHolder.INSTANCE, not before.
                 */
                private static class SingletonHolder { 
                  private static final Singleton INSTANCE = new Singleton();
                }
              
                public static Singleton getInstance() {
                  return SingletonHolder.INSTANCE;
                }
              }
              (from [url http://sourcemaking.com/design_patterns/singleton/java/1]sourcemaking.com)

              And there is on the same note a variant -I believe proposed in Effective Java 2nd Ed.- using enum for the holder.