Skip to main content

Knowing Singelton

Singelton pattern in one of the most commonly used and talked about design pattern. Many appreciates it usefulness and many advocate against it. In this post we are not going to discuss all that but will concentrate on its implementation in c#.

Type:
It is a creational design pattern.

Intent:
It ensures that only one instance of the class exists.

Usage:
It is generally used when only one instance of a class is required. Thus, it can be seen to be used in logging frameworks, configuration objects etc.

The ownership of instance creation lies with the class itself. This is because we can not ensure that only one instance will ever exists for the class if the responsibility lies with someone else.

The class will instantiate the object when it will be used for the first time. This also ensures lazy initialization.

Point to consider:
Singelton object is mostly made accessible globally and thus being abused by being used as global variable. We must keep in mind that not only the singelton object but the whole object graph associated to it (which can be traversed through it) becomes global. Though most of us will say no to using global variables but will readily say yes to singeltons.

Simple Implementation:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PlayingWithSingelton
{
    public class SimpleSingelton
    {
        private static SimpleSingelton _instance;

        private SimpleSingelton()
        {
            
        }

        public static SimpleSingelton CurrentInstance
        {
            get
            {
                if(_instance == null)
                {
                    _instance = new SimpleSingelton();
                }
                return _instance;
            }
        }

        public void Print()
        {
            Console.WriteLine(this.GetHashCode());
        }
    }
}

In our SimpleSingelton class we have created a private constructor. This will ensure that no one else can instantiate SimpleSingelton by calling its constructor.

We have also create a private data member of type SimpleSingelton. This will hold the lone instance of SimpleSingelton. We have marked it static because we will access it from static members (property or method).

We have created a static property which will check if _instance is null or not. If it is null it will instantiate it and then return the _instance.

This implementation looks promising but it is not thread safe. In a multi-threaded scenario two threads can check for the nullability of _instance almost at the same time and thus can create two instances of SimpleSingelton as both will find _instance null.

Partially Thread Safe Implementation


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace PlayingWithSingelton
{
    public class PartiallyThreadSafeSingelton
    {
        private static volatile PartiallyThreadSafeSingelton _instance;
        private static readonly Object Locker = new object();

        private PartiallyThreadSafeSingelton()
        {
            
        }

        public static PartiallyThreadSafeSingelton CurrentInstance
        {
            get
            {
                if(_instance == null)
                {
                    lock (Locker)
                    {
                        _instance = new PartiallyThreadSafeSingelton();
                    }
                }

                return _instance;

            }
        }
    }
}

In our PartiallyThreadSafeSingelton class we have marked the _instance as volatile this means that the most up-to date  value of _instance will be used and the value will be requested every time we will use _instance although in the previous statements _instance value would have been retrieved.

In our getter for CurrentInstance we have use a lock. This will ensure that only one thread will create an instance at a time. Wait!!! But, multiple threads can check for nullability simulatneously and then one thread can wait for the other to create instance and release lock. Then it will also create an instance.

What if we check for nullability just before instantiating? Yes, we should.

Process intensive Thread Safe Implementation


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PlayingWithSingelton
{
    public class ProcessIntensiveThreadSafeSingelton
    {
        private static volatile ProcessIntensiveThreadSafeSingelton _instance;
        private static readonly Object Locker = new object();

        private ProcessIntensiveThreadSafeSingelton()
        {
            
        }

        public static ProcessIntensiveThreadSafeSingelton CurrentInstance
        {
            get
            {
                lock (Locker)
                {
                    if (_instance == null)
                        _instance = new ProcessIntensiveThreadSafeSingelton();
                }
                return _instance;
                
            }
        }
    }
}

It is process intensive to acquire a lock every time. As the instantiation will happen only once. Thus we can change our implementation a bit and can check for nullability one more time but before acquiring lock.

Thread Safe Implementation


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PlayingWithSingelton
{
    public class ThreadSafeSingelton
    {
        private static volatile ThreadSafeSingelton _instance;
        private static readonly Object Locker = new object();

        private ThreadSafeSingelton()
        {
            
        }

        public static ThreadSafeSingelton CurrentInstance
        {
            get
            {
                if (_instance == null)
                {
                    lock (Locker)
                    {
                        if (_instance == null)
                            _instance = new ThreadSafeSingelton();
                    }
                }
                return _instance;
                
            }
        }
    }
}

In future posts we will discuss more about singelton and its usage.

Comments

Popular posts from this blog

Laravel XAMPP MySQL artisan migrate install error mysql.sock

In my previous post I wrote about setting up Laravel 4 on Mac with XAMPP . When I tried to use migrations (using artisan) I faced some issue. I will also post about Laravel migrations soon.    php artisan migrate:install Error :                                                     [PDOException]                                       SQLSTATE[HY000] [2002] No such file or directory                                              Solution : We need to tell artisan which mysql we want it to use. For this to work we need to porivde it with mysql.sock which we want it to use. So change your database settings like this: 'mysql' => array( 'driver'    => 'mysql', 'host'      => 'localhost',     'unix_socket' => '/Applications/xampp/xamppfiles/var/mysql/mysql.sock', 'database'  => 'wedding', 'username'  => 'root', 'password'  => '', '

Add (Drop) a new article (table) at publisher in merge replication

Let us add the article using the GUI first. First of all create the table on publisher database. Now right click on the publisher and select properties from the menu. Click on articles. Uncheck the - "Show only checked articles in the list" checkbox, in order to see the newly added table. Select the table as shown in the figure below. Press ok The article has now been added to the publisher We now need to recreate the snapshot Right click the publication and select – “View snapshot agent status”. Click start to regenerate snapshot. Now right click on the subscription (I have both on same server you may have on different servers) and select “View synchronization status” Click on start on the agent. The schema changes will propagate to the client if you have "Replicate schema changes" property set to true in the publisher.

Check SQL Server Job status (State) using sp_help_job and xp_sqlagent_enum_jobs

This article is about checking the status of a SQL job. In our work place we have lot of SQL jobs. These jobs will run whole day and are business critical. They will load the data and generate extracts which will be used by business people. Thus, it becomes quite essential to support the system efficiently so that the job finishes in time and as desired. Also, while designing a new system sometimes we need to check the dependency of one job over another. In such scenario we need to check whether a particular job has finished or not. All this can be achieved in SQL Server by using the procedures:- sp_help_job xp_sqlagent_enum_jobs Note: xp_sqlagent_enum_jobs is an undocumented proc inside of sp_help_job and is used extensively to get SQL agent job information. sp_help_job: This procedure gives some insight into the status, and information, about a job. This stored procedure provides information such as last start time, job status etc. Syntax sp_help_job { [ @job_id= ] jo