потокобезопасный Singleton
От: adontz Грузия http://adontz.wordpress.com/
Дата: 08.08.05 21:35
Оценка: :)
Мне тут стало интересно, такой синглтон потокобезопасный? Двух экземплятор не создасться?
public class MySingleton
{
    private static MySingleton _instance = new MySingleton();
    
    public static MySingleton Instance
    {
        get
        {
            return _instance;
        }
    }
}



12.08.05 11:06: Перенесено из '.NET'
A journey of a thousand miles must begin with a single step © Lau Tsu
потокобезопасный Singleton
От: Аноним  
Дата: 08.08.05 22:02
Оценка:
Нет, не создастся.

Данная информация предоставляется на условиях «КАК ЕСТЬ», без предоставления каких-либо гарантий и прав. Используя данную информацию, вы соглашаетесь с тем, что (i) Майкрософт не несет ответственности за использование вами данной информации и (ii) вы принимаете на себя весь риск, связанный с использованием данной информации.


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re: потокобезопасный Singleton
От: retalik www.airbandits.com/
Дата: 08.08.05 22:35
Оценка: 84 (7) +1
Здравствуйте, adontz, Вы писали:

A>Мне тут стало интересно, такой синглтон потокобезопасный? Двух экземплятор не создасться?


Да, там специально при обращении к статическим полям вставляется код для проверки гарантированной инициализации.
В некоторых случаях это ведет к тормозам, кстати.

А вот кусочек из MSDN:

.NET Singleton Example

// .NET Singleton
sealed class Singleton 
{
    private Singleton() {}
    public static readonly Singleton Instance = new Singleton();
}

This version is dramatically simpler and more intuitive. Is it still a singleton? Let's look at what changed and then decide. We modified the class itself to be sealed (non-inheritable), the lazy initialization code is removed, the Instance() method is removed, and we modified the _instance variable extensively. The changes to the _instance variable include modifying the access level to public, marking the variable as read-only, and initializing the variable at declaration time. Here we can directly define the behavior we want and not be concerned with potential unwanted side effects of the implementation. So what about the advantages of using lazy initialization and the hazards of multiple threads? All of the correct behaviors are built into the .NET Framework. Let's take the first case, lazy initialization.

The main reasons for using lazy initialization initially were to get the behavior of having an instance created on only the first call to the Instance() method, and because there was some openness in the C++ spec that did not define the exact initialization order of static variables. To get desired singleton behavior in C++, a workaround that involved the use of lazy initialization was necessary. What we really care about is that we get the instance created either on or just before the first call to (in this case) the Instance property, and that we have a defined initialization order for static variables in a class. With the .NET Framework, this is exactly the behavior we get. The Framework, during the JIT process, will initialize the static property when (and only when) any method uses this static property. If the property is not used, then the instance is not created. More precisely, what happens during JIT is that the class gets constructed and loaded when any static member of the class is used by any caller. In this case the result is the same.

What about thread-safe initialization? The Framework addresses this too. The Framework internally guarantees thread safety on static type initialization. In other words, in the example above, there is only one instance that would ever be created of the Singleton class. Note also that the property field used to hold the instance of the class is called Instance. This choice better illustrates that this value is an instance of the class as part of the discussion in this article. In the Framework itself there are several classes that use this type of singleton, although the property name used is called Value instead. The concept is exactly the same.

Успехов,
Виталий.
Потокобезопасный Singleton
От: Аноним  
Дата: 09.08.05 07:25
Оценка: +1
В этом блоге увидел другой способ создания синглтона:

public class Singleton
{
 private static Singleton _instance;
 public static Singleton GetInstance()
 {
  if (_instance == null)
  {
   lock (typeof(Singleton))
   {
    if (_instance == null)
    {
     _instance = new Singleton();
    }
   }
  }
  return _instance;
 }
}


Плюс такой реализации, в том, что объект создается при первом вызове метода GetInstance(), т.е. нет вызовов — нет объекта.
На мой взгляд, использовать данную реализацию стоит только в каких то оссобенных и редких случаях.
________________________________
Best regards, Oleg Ufaev
Rostov .Net User Group
Конкурсная заявка


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Потокобезопасный Singleton
От: Аноним  
Дата: 09.08.05 07:24
Оценка:
В этом блоге увидел другой способ создания синглтона:

public class Singleton
{
 private static Singleton _instance;
 public static Singleton GetInstance()
 {
  if (_instance == null)
  {
   lock (typeof(Singleton))
   {
    if (_instance == null)
    {
     _instance = new Singleton();
    }
   }
  }
  return _instance;
 }
}


Плюс такой реализации, в том, что объект создается при первом вызове метода GetInstance(), т.е. нет вызовов — нет объекта.
На мой взгляд, использовать данную реализацию стоит только в каких то оссобенных и редких случаях.
________________________________
Best regards, Oleg Ufaev
Rostov .Net User Group
Конкурсная заявка


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re: Потокобезопасный Singleton
От: Аноним  
Дата: 09.08.05 07:31
Оценка:
Здравствуйте, Аноним, Вы писали:

А>В этом блоге увидел другой способ создания синглтона:


А>
public class Singleton
А>{
А> private static Singleton _instance;
А> public static Singleton GetInstance()
А> {
А>  if (_instance == null)
А>  {
А>   lock (typeof(Singleton))
А>   {
А>    if (_instance == null)
А>    {
А>     _instance = new Singleton();
А>    }
А>   }
А>  }
А>  return _instance;
А> }
А>}
А>


и для чего тут нужен lock если он не обрамляет if ?
Потокобезопасный Singleton
От: Аноним  
Дата: 09.08.05 07:37
Оценка: -1
Потокобезопасный Singleton:

public class Singleton
{
private static Singleton instance = null;
private static object root = new object();

private Singleton() { }

public Singleton Instance
{
get
{
lock(root)
if(instance == null)
instance = new Singleton();

return instance;
}
}
}


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re[2]: Потокобезопасный Singleton
От: valmond Россия http://blogs.technet.com/valmond/
Дата: 09.08.05 07:45
Оценка:
А>>
public class Singleton
А>>{
А>> public static Singleton GetInstance()
А>> {
А>>  if (_instance == null)
А>>  {
А>>   lock (typeof(Singleton))
А>>   {
А>>    if (_instance == null)
А>>    {
А>>     _instance = new Singleton();
А>>    }
А>>   }
А>>  }
А>>  return _instance;
А>> }
А>>}
А>>


А>и для чего тут нужен lock если он не обрамляет if ?


См. внимательнее.
Стандартная двойная проверка
Заметки — SharePoint & InfoPath
http://blogs.technet.com/valmond/
Re: Потокобезопасный Singleton
От: Аноним  
Дата: 09.08.05 07:56
Оценка:
>и для чего тут нужен lock если он не обрамляет if ?

Такая конструкция используется для того, чтобы устранить синхронизацию при каждом вызове этого метода. Синхронизация будет производиться до тех пор, пока _instance будет null.

Второе условие проверки на null, нужно для избежания создания нескольких экземпляров класса Singleton (так как несколько потоков могут пройти первое условие проверки на null). Пример Rafiki не учитывает эту ситуацию.

Я думаю, что единственное чего здесь не хватает, для полноценной потокобезопасности — это объявление поля _instance как volatile, для обеспечения атомарности сравнения (_instance == null).
________________________________
Best regards, Oleg Ufaev
Rostov .Net User Group
Конкурсная заявка


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re[3]: Потокобезопасный Singleton
От: Александр Сергеевич Россия  
Дата: 09.08.05 07:56
Оценка:
Здравствуйте, valmond, Вы писали:
V>См. внимательнее.
V>Стандартная двойная проверка
А зачем два if? А почему не один в lock?
/* silent */
Re[2]: Потокобезопасный Singleton
От: Tom Россия http://www.RSDN.ru
Дата: 09.08.05 07:58
Оценка:
А>и для чего тут нужен lock если он не обрамляет if ?
Это называется double check lock pattern
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Народная мудрось
всем все никому ничего(с).
Re[4]: Потокобезопасный Singleton
От: valmond Россия http://blogs.technet.com/valmond/
Дата: 09.08.05 08:06
Оценка: 1 (1)
Здравствуйте, Александр Сергеевич, Вы писали:

АС>Здравствуйте, valmond, Вы писали:

V>>См. внимательнее.
V>>Стандартная двойная проверка
АС>А зачем два if? А почему не один в lock?

После первого if-a мы проверяем, что достаточное условие для наложения лока и создания объекта выполняется.
Накладываем lock и проверяем, что после проверки достаточного условия второй поток еще не создал этот инстанс. Т.е. проверяем необходимое условие и делаем выводы.
Заметки — SharePoint & InfoPath
http://blogs.technet.com/valmond/
Re: потокобезопасный Singleton
От: hugo Австрия  
Дата: 09.08.05 08:18
Оценка:
Здравствуйте, adontz, Вы писали:

A>Мне тут стало интересно, такой синглтон потокобезопасный? Двух экземплятор не создасться?


Можно еще так

   public class Singleton<T>
   {
      static private T _instance;
      static private object _lock = new object();

      protected Singleton()
      {
      }

      public static T Instance
      {
         get
         {
            if(_instance == null)
            {
               lock(_lock)
               {
                  if(_instance == null)
                  {
                     ConstructorInfo ci = type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic,
                        null,
                        new Type[] { },
                        null);
                     _instance = (T)ci.Invoke(null);
                  }
               }
            }
            return _instance;
         }
      }
   }
Re: Потокобезопасный Singleton
От: Lloyd Россия  
Дата: 09.08.05 08:20
Оценка: 63 (6)
Здравствуйте, olegmad, Вы писали:

O>Плюс такой реализации, в том, что объект создается при первом вызове метода GetInstance(), т.е. нет вызовов — нет объекта.

O>На мой взгляд, использовать данную реализацию стоит только в каких то оссобенных и редких случаях.

Есть более элегантное решение:

public sealed class Singleton {
    private sealed class SingletonInstanceHolder {
        private SingletonInstanceHolder() {}
        public static readonly Singleton SingletonInstance = new Singleton();
    }

    private Singleton() {}
    
    public static Singleton Instance {
        get { return SingletonInstanceHolder.SingletonInstance; }
    }
}
... << RSDN@Home 1.1.4 stable rev. 510>>
Re: потокобезопасный Singleton
От: vitaly_spb Россия  
Дата: 09.08.05 08:41
Оценка:
Это не самый потокобезопасный метод. Возможные имплементации есть здесь:

http://dofactory.com/Patterns/PatternSingleton.aspx

А также можешь поискать про Double lock

http://www.google.ru/search?hl=ru&amp;q=double+lock+singleton&amp;lr=
...Ei incumbit probatio, qui dicit, non qui negat...
Re[2]: потокобезопасный Singleton
От: Lloyd Россия  
Дата: 09.08.05 09:51
Оценка:
Здравствуйте, hugo, Вы писали:

public class Singleton<T> where T: new()

И вместо Reflection-а будет просто new T();
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[3]: потокобезопасный Singleton
От: Аноним  
Дата: 09.08.05 10:35
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>И вместо Reflection-а будет просто new T();


+ "дырка" в паттерне
Re[4]: потокобезопасный Singleton
От: hugo Австрия  
Дата: 09.08.05 10:40
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Lloyd, Вы писали:


L>>И вместо Reflection-а будет просто new T();


А>+ "дырка" в паттерне

Да, вот, собственно говоря, поэтому и остановился на рефлекшине
Если скорость большая не нужна...
Кроме того у меня там еще есть "точка расширения" — можно подсунуть другой тип с клиентской реализацией —
которую я убрал из примера.
Re[5]: потокобезопасный Singleton
От: Аноним  
Дата: 09.08.05 10:43
Оценка:
Здравствуйте, hugo, Вы писали:

H>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, Lloyd, Вы писали:


L>>>И вместо Reflection-а будет просто new T();


А>>+ "дырка" в паттерне

H>Да, вот, собственно говоря, поэтому и остановился на рефлекшине
H>Если скорость большая не нужна...

Думается, разница в скорость здесь не критична

H>Кроме того у меня там еще есть "точка расширения" — можно подсунуть другой тип с клиентской реализацией —

H>которую я убрал из примера.

А вот паттерны скрещивать не стоит (фабрика и синглетон).
Re[6]: потокобезопасный Singleton
От: hugo Австрия  
Дата: 09.08.05 10:46
Оценка:
Здравствуйте, Аноним, Вы писали:

H>>Кроме того у меня там еще есть "точка расширения" — можно подсунуть другой тип с клиентской реализацией —

H>>которую я убрал из примера.

А>А вот паттерны скрещивать не стоит (фабрика и синглетон).


А если надо? Тут либо фабрика с сингелтоном, либо наоборот
Что еще можете посоветовать?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.