Casper-SC
@Casper-SC
Программист (.NET)

Есть несколько способов создания единственного экземпляра класса. Есть ли смысл использовать в многопоточной среде второй вариант (см. в теме)?

что может заставить использовать второй вариант? Я, насколько понимаю, первый вариант вполне справляется со своей задачей и так же создаёт экземпляр класса при первом обращении к этому классу. Так зачем мне использовать второй вариант? Так, на всякий случай: Зачем двойная проверка во втором варианте я прекрасно понимаю.

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;
            }
        }
    }


Я просто часто сижу и думаю, какой способ использовать.

Всё, понял. Я почему-то думал, что в статическом конструкторе не будет проблем с многопоточностью. Кто-то очень давно мне такое сказал и я принял за истину. Хотя, если подумать, то проблемы должны быть такие же, как и без лока и двойной проверки во втором варианте.
  • Вопрос задан
  • 337 просмотров
Пригласить эксперта
Ответы на вопрос 3
@Melz
В первом случае будет не очень если 2 потока одновременно потребуют инстанс. Создастся два инстанса.
Второй вариант - классическая реализация для всех языков программирования. В .Net есть более простые способы сделать Singleton.

В С# есть некоторые фичи про которые стоит почитать: инициализация статических конструкторов и типов.
Вам надо это (работает в тредах и даже немного lazy):
public sealed class Singleton
{
    public static Singleton Instance { get; } = new Singleton();
    private Singleton() { /* some initialization code */ }
}

О синглетоне в С# 6
О реализации в C#
Ответ написан
Комментировать
@dmitryKovalskiy
программист средней руки
Я бы рекомендовал выбор между вторым и DI-контейнером с контролем количества объектов.
Ответ написан
@Mercury13
Программист на «си с крестами» и не только
Первый-то создаёт, однако…
• Если во время создания напросится другой поток, будут созданы два экземпляра. В «не-мусорных» языках второй экземпляр будет «висеть» и его никак не уничтожишь.
• При определённом устройстве среды исполнения (instance присваивается раньше, чем срабатывает конструктор) система может отдать другому потоку ссылку на неготовый экземпляр.

От создания двух экземпляров второе точно защищает. Я не знаком с моделью памяти C# и потому не могу сказать, насколько второе защищает от неготового экземпляра; кажется, нужен ещё модификатор volatile.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы