Cozzbie
Cozzbie

Reputation: 1055

Design Patterns: The Singleton confusion

I have been doing some major design patterns reading and the subject SINGLETONS is bugging me the HELL out. In basic OOP we learn that STATIC variables are CLASS level variables and thus can basically only have ONE INSTANCE.

Now the basic implementation of a singleton is intended to return a STATIC variable which holds a new object of its own class and which is instantiated only once.

class MyClass {
      public static MyClass initVar;

      private MyClass (){}

      public static getInstance (){
           if(initVar == null){
              initVar = new MyClass();
           }
           return initVar;
      }

}

In the example that was being used to explain this using JVM, it was said that in a multithreaded system more than one instance of this class can be initialized if the getInstance variable isn't made thread safe by using the synchronize directive before the method name, so here in lies my confusion and my question.

the example...

var MyClass a = MyClass.getInstance(); //non thread-safe

now from the example it is said that this non thread-safe implementation can lead to MULTIPLE instances of the MyClass variable intVar that was earlier on declared STATIC. How can we have multiple STATIC variables being returned by ONE CLASS?

Even if the call creates multiple MyClass objects, shouldn't intVar still just simply point to the newest MyClass object that was created on it and thus we should still have ONE CLASS INSTANCE, the last one created which intVar is now pointing to?

Can we actually have multiple STATIC variables for every non thread-safe call on MyClass.getInstance()?

How can this be?

Upvotes: 0

Views: 164

Answers (2)

Jose Llausas
Jose Llausas

Reputation: 3406

The problem with multithreaded access to a singleton is what is called a 'race condition' The problem is not that it will return different instances. The problem is when multiple threads try to access the same data at the same time. You need to sync protect the data, so only one thread is accessing your singleton at a given time.

One technique I use for singletons is using 'lazy instantiation':

class MyClass{
public static final MyClass initVar = 0;

public static MyClass getInstance(){
     if (self.initVar == 0){
         // -> Lazy instantiation, this should only happen once. 
         // You can add some assert code here to verify that this is only 
         // happening once in your application. With lazy instantiation you 
         // wait until you actually need the object to create it.
         self.initVar = new MyClass();   
     }

     return initVar;
    }

}

Upvotes: 1

duffymo
duffymo

Reputation: 308733

Here's how a Singleton ought to be implemented:

class MyClass {
      public static final MyClass initVar = new MyClass();

      private MyClass (){}

      public static MyClass getInstance (){
           return initVar;
      }
}

Perfectly thread safe.

You don't include any information about mutable state in your Singleton. If you add any, you'll have to synchronize.

You realize, after all your research, that Singleton would be voted off the island if the GoF book was written today. Google goes to a great deal of trouble to root out Singletons.

Upvotes: 1

Related Questions