Singleton Design Pattern
Multiple Users playing one game.

Singleton Design Pattern

This Design Pattern is one of the Creational Design Patterns.

The Singleton pattern ensures that the class has only one instance and provides a global point of access to it.

Example 1:

On your mobile, if there is an app running and anytime you open it, every time you get the same instance of the app. Your mobile does not start the app again. (Except if the app got crashed)

Here the app is the instance of is the Singleton class. And in order to access the app, you are calling getInstance method provided by the app.

public class Application {

   static protected Application app;

   private Application(){

   }

   public static Application getInstance(){

       if(app == null){

           app = new Application();   

       }

       return app;

   }

   public String getUpdate(){

       return "Here are the Updates";

   }

}


Now as a user you call:

       Application app = Application.getInstance();

app.getUpdate();

And the next time you open again the app and check the update, you will be getting the same instance and the app will get you the updates.        

Points to be noted:

1) The Constructor is private.

2) Singleton variable is "static private".

3) Only one way to access the instance i.e. call getInstance() method.

(This is the example of Lazy initialization. Think of this as when you are hungry and instead of having the food pre-prepared, you start cooking at that time only, end up waiting for some time before the food gets cooked.)

Why static: The application instance gets memory only once being static.

Why private: As the variable is static, it can be accessed from outside. In order to ensure that the instance is only accessible through the getInstance method, we make it private.

Why constructor is private?

Globally there should be only one instance of Singleton class.

If we make the constructor public then apart from the getInstance method any other class could instantiate the Singleton class.

One very important point that needs to be considered is thread safety.

Example 2:

Logging service is used to log different types of messages.

Different threads use the single instance of this service at the same time.

That means different threads could instantiate the same variable.

Therefore to tackle this problem, let’s modify the code a little bit.

Here we will always check the state of the variable before instantiating it.

       if (app == null) {         

               app = new LogApplication();                        

       }   

Let's create 2 threads trying to instantiate 2 threads.

//First Thread

Thread t1 = new Thread(new Runnable() {

           @Override

           public void run() {

               LogApplication ins1 = LogApplication.getInstance();

               System.out.println("Hash of First Instance: " + ins1.hashCode());

           }

       });

//Second Thread

       Thread t2 = new Thread(new Runnable() {

           @Override

           public void run() {

               LogApplication ins2 = LogApplication.getInstance();

               System.out.println("Hash of Second Instance: " + ins2.hashCode());

           }

       });

The above code will return different hash codes.

That means the LogApplication is still not thread safe.

Why?

Both the threads could call getInstance() method at the same time.

The app == null condition will return for both the thread. So, two different instances of the same class will be created. That will break the singleton principle.

So to solve the above problem let's synchronize both the threads.

But because synchronize slows down the performance; therefore put another null check before synchronizing.

(We were synchronizing so as to avoid both threads from creating separate instances i.e. why put unnecessary synchronize when the variable is already instantiated.)

if (app == null) {

           synchronized (LogApplication.class)

           {

               if(app==null)

               {

                   app = new LogApplication();

               }

           }

       }

Final Thoughts:

In the game Mini Malaysia up to a certain number of different players can play simultaneously during online battles. This game is one of the applications of Singleton DP.

Singleton DP is used to make sure that only one instance of a class is created and it is accessed globally.

GitHub: https://github.com/tanu02/Design-Patterns/tree/master/Singleton/src

Thanks for reading the article. I hope it helps.

要查看或添加评论,请登录

社区洞察

其他会员也浏览了