B
B
Boris the Animal2015-12-04 11:41:46
Programming
Boris the Animal, 2015-12-04 11:41:46

There are several ways to create a single instance of a class. Does it make sense to use the second option in a multi-threaded environment (see the topic)?

what can force to use the second variant? As far as I understand, the first option copes with its task quite well and also creates an instance of the class the first time this class is accessed. So why should I use the second option? So, just in case: Why double check in the second variant I perfectly understand.

public class DataProvider
    {
        static DataProvider()
        {
            Instance = new DataProvider();
        }

        private DataProvider()
        {
            // Init data
        }

        public static DataProvider Instance { get; private set; }
    }

public class DataProvider
    {
        private static DataProvider _instance;
        private static readonly object _syncLock = new object();

        private DataProvider()
        {
            // Init data
        }

        public static DataProvider Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_syncLock)
                    {
                        if (_instance == null)
                        {
                            _instance = new DataProvider();
                        }
                    }
                }

                return _instance;
            }
        }
    }

I just often sit and think which way to use.
Got it. For some reason, I thought that there would be no problems with multithreading in a static constructor. Someone told me this a long time ago and I took it for the truth. Although, if you think about it, the problems should be the same as without lock and double check in the second option.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
M
Melz, 2015-12-04
@melz

In the first case, it will not be very good if 2 threads simultaneously require an instance. Two instances will be created.
The second option is a classic implementation for all programming languages. There are easier ways in .Net to make a Singleton.
There are some features in C# that are worth reading about: initialization of static constructors and types.
You need this (works in threads and even a little lazy):

public sealed class Singleton
{
    public static Singleton Instance { get; } = new Singleton();
    private Singleton() { /* some initialization code */ }
}

About singleton in C# 6
About implementation in C#

D
Dmitry Kovalsky, 2015-12-04
@dmitryKovalskiy

I would recommend choosing between the second and DI container with control over the number of objects.

M
Mercury13, 2015-12-04
@Mercury13

The first one creates, however...
• If another thread is asked during creation, two instances will be created. In "non-garbage" languages, the second instance will "hang" and cannot be destroyed in any way.
• With a certain runtime device (instance is assigned before the constructor fires), the system can give another thread a reference to an unprepared instance.
From creation of two copies the second precisely protects. I'm not familiar with the C# memory model, so I can't say how much the latter protects against an unprepared instance; seems to need another volatile modifier.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question