threads – singleton

As from one of my previous posts about threading in csharp (c#), well with using Singletons you can use similar data between two different threads running.

In basics a singleton is when you want to have a single class instance so that you can share this class so that every time that you use it (even across threads) will only access the same class, it is very useful for when you have a printer spool so that you do not want to have x amount of printer spools (spool is when you have a list of print tasks waiting to print) and thus you only want to have one instance of a printer spool !!.

I have used the singleton creation from Microsoft website, that creates a singleton class that is thread safe which means that I am using the lock method that will lock on a object to stop thread contention and thus only creates a new instance of a Singleton class so that each thread will only get access to a single instance of that class.

So when you want to gain access to that single instance, you just call the

Singleton theSingleton = Singleton.Instance;

So here is the full source code, and below is the output where the output is displaying the value is incrementing otherwise if is was not a singleton class, the main class would print out 0-4 and also the runthismethod would output 0-9 instead!.

using System;
using System.Threading;
 
namespace monotestproject
{
	public sealed class Singleton
	{
		private static int _value;
		private static volatile Singleton instance;
		private static object syncRoot = new Object();
 
		public Singleton() { _value = 0;}
 
		public static Singleton Instance
		{
			get { 
				if (instance == null)
				{
					lock(syncRoot)
					{
						if (instance == null)
							instance = new Singleton();
					}
				}
				return instance;
			}
			private set {}
		}
 
		public int theValue 
		{
			get { return _value;}
			set { _value = value;}
		}
	}
 
	class MainClass
	{
		public static void Main (string[] args)
		{
			Singleton theSingleton = Singleton.Instance;
			// initialize the RunThisMethod as a thread
			Thread theThread = new Thread(RunThisMethod);
			theThread.Start();
 
			for (int j = 0; j < 5; j++)
			{
				theSingleton.theValue++;
				Console.WriteLine("Main Singleton value " + theSingleton.theValue);
				Thread.Sleep(100);
			}
		}
 
		// the method to create as a threadable method
		public static void RunThisMethod()
		{
			Singleton runsSingleton = Singleton.Instance;		
			for (int i =0; i < 10; i++)
			{
				runsSingleton.theValue++;
				Console.WriteLine("RunThisMethod Singleton value " + runsSingleton.theValue);
				Thread.Sleep(45);
			}
		}
	}
}

here is my output, as you can I am getting the singleton value incrementing, which is what should be happening.

Main Singleton value 1
RunThisMethod Singleton value 2
RunThisMethod Singleton value 3
RunThisMethod Singleton value 4
Main Singleton value 5
RunThisMethod Singleton value 6
RunThisMethod Singleton value 7
Main Singleton value 8
RunThisMethod Singleton value 9
RunThisMethod Singleton value 10
Main Singleton value 11
RunThisMethod Singleton value 12
RunThisMethod Singleton value 13
Main Singleton value 14
RunThisMethod Singleton value 15

5 thoughts on “threads – singleton”

  1. I found an issue when i put MainSingleton and RunThisMethod do NOT sleep:

    Main Singleton value 1
    RunThisMethod Singleton value 1

  2. Um.. you should never have a set-up for a singleton where the main and run method singleton would be 1. What is your code ?

  3. My code:

    public sealed class Singleton
        {
            private static int _value;
            private static volatile Singleton instance;
            private static object syncRoot = new Object();
     
            public Singleton() { _value = 0; }
     
            public static Singleton Instance
            {
                get
                {
                    if (instance == null)
                    {
                        lock (syncRoot)
                        {
                            if (instance == null)
                                instance = new Singleton();
                        }
                    }
                    return instance;
                }
                private set { }
            }
     
            public int theValue
            {
                get { return _value; }
                set { _value = value; }
            }
        }
     
        class Program
        {
            public static void Main(string[] args)
            {
                Singleton theSingleton = Singleton.Instance;
                // initialize the RunThisMethod as a thread
                Thread theThread = new Thread(RunThisMethod);
                theThread.Start();
     
                for (int j = 0; j < 5; j++)
                {
                    theSingleton.theValue++;
                    Console.WriteLine("Main Singleton value " + theSingleton.theValue);
                    //Thread.Sleep(100);
                }
                Console.ReadLine();
            }
     
            // the method to create as a threadable method
            public static void RunThisMethod()
            {
                Singleton runsSingleton = Singleton.Instance;
                for (int i = 0; i < 10; i++)
                {
                    runsSingleton.theValue++;
                    Console.WriteLine("RunThisMethod Singleton value " + runsSingleton.theValue);
                    //Thread.Sleep(45);
                }
            }
        }
  4. RunThisMethod Singleton value 1
    Main Singleton value 1
    Main Singleton value 3
    Main Singleton value 4
    RunThisMethod Singleton value 2
    RunThisMethod Singleton value 6
    RunThisMethod Singleton value 7
    RunThisMethod Singleton value 8
    RunThisMethod Singleton value 9
    RunThisMethod Singleton value 10
    RunThisMethod Singleton value 11
    RunThisMethod Singleton value 12
    RunThisMethod Singleton value 13
    Main Singleton value 5
    Main Singleton value 14

    The issue happen when i try that code several times, I think it happen when 2 thread access the variable to get value at the same time.

  5. Or you can test this code, almost debug time it pass, but seldom it fail

    public sealed class Singleton
        {
            private static int _value;
            private static volatile Singleton instance;
            private static object syncRoot = new Object();
     
            public Singleton() { _value = 0; }
     
            public static Singleton Instance
            {
                get
                {
                    if (instance == null)
                    {
                        lock (syncRoot)
                        {
                            if (instance == null)
                                instance = new Singleton();
                        }
                    }
                    return instance;
                }
                private set { }
            }
     
            public int theValue
            {
                get { return _value; }
                set { _value = value; }
            }
        }
     
        class Program
        {
            public static void Main(string[] args)
            {
                Singleton theSingleton = Singleton.Instance;
                // initialize the RunThisMethod as a thread
                Thread theThread1 = new Thread(RunThisMethod1);
                theThread1.Start();
     
                Thread theThread2 = new Thread(RunThisMethod2);
                theThread2.Start();
     
                for (int j = 0; j < 5; j++)
                {
                    theSingleton.theValue++;
                    Console.WriteLine("Main Singleton value " + theSingleton.theValue);                
                }
                // Wait all calculate complete and show the result, it should equal 5
                Thread.Sleep(200);
                Console.WriteLine("Last value (shold equal 5): " + theSingleton.theValue);   
                Console.ReadLine();
            }
     
            // the method to create as a threadable method
            public static void RunThisMethod1()
            {
                Singleton runsSingleton = Singleton.Instance;
                for (int i = 0; i < 10; i++)
                {
                    runsSingleton.theValue+=2;
                    Console.WriteLine("RunThisMethod 1 Singleton value " + runsSingleton.theValue);                
                }
            }
     
            // the method to create as a threadable method
            public static void RunThisMethod2()
            {
                Singleton runsSingleton = Singleton.Instance;
                for (int i = 0; i < 10; i++)
                {
                    runsSingleton.theValue-=2;
                    Console.WriteLine("RunThisMethod 2 Singleton value " + runsSingleton.theValue);                
                }
            }
        }

Leave a Reply

Your email address will not be published.