2010-03-26 3 views
3

В настоящее время у меня есть следующий класс:Является ли Structuremap singleton потоком безопасным?

public class PluginManager 
{ 
    private static bool s_initialized; 
    private static object s_lock = new object(); 

    public static void Initialize() { 
     if (!s_initialized) { 
      lock (s_lock) { 
       if (!s_initialized) { 
        // initialize 

        s_initialized = true; 
       } 
      } 
     } 
    } 
} 

Важным моментом здесь является то, что Initialize() должна быть выполнена только один раз в то время как приложение работает. Я думал, что я бы реорганизовать это в одноплодный класс, так как это было бы более поточно ?:

public sealed class PluginService 
{ 
    static PluginService() { } 
    private static PluginService _instance = new PluginService(); 
    public static PluginService Instance { get { return _instance; } } 

    private bool s_initialized; 

    public void Initialize() { 
     if (!s_initialized) 
     { 
      // initialize 

      s_initialized = true; 
     } 
    } 
} 

Вопрос один, он по-прежнему необходим иметь блокировку здесь (я удалил его), так как мы будем только когда-либо работать над одним и тем же экземпляром?

Наконец, я хочу использовать DI и структуру карту, чтобы инициализировать мой servcices поэтому я переработан, как показано ниже:

public interface IPluginService { 
    void Initialize(); 
} 

public class NewPluginService : IPluginService 
{ 
    private bool s_initialized; 
    public void Initialize() { 
     if (!s_initialized) { 
      // initialize 

      s_initialized = true; 
     } 
    } 
} 

И в моем реестре:

  ForRequestedType<IPluginService>() 
      .TheDefaultIsConcreteType<NewPluginService>().AsSingletons(); 

Это работает, как ожидалось (Singleton возвращая значение true в следующем коде):

  var instance1 = ObjectFactory.GetInstance<IPluginService>();   
     var instance2 = ObjectFactory.GetInstance<IPluginService>(); 

     bool singleton = (instance1 == instance2); 

Так что мой следующий вопрос: решение структурной карты как потокобезопасное, как класс singleton (второй пример). Единственным недостатком является то, что это все равно позволит напрямую создавать NewPluginService (если не использовать структурную карту).

Большое спасибо, Бен

ответ

3

Я хотел бы сделать несколько рекомендаций:

  • логический флаг должен быть volatile
  • сделать ваш одноточечно экземпляр readonly
  • инициализация не поточно, независимо от того, что у вас есть только один экземпляр ... поэтому он должен быть синхронизирован

    public sealded class PluginService 
    { 
    
    static PluginService() { } 
    
    //make the instance readonly 
    private static readonly PluginService _instance = new PluginService(); 
    public static PluginService Instance { get { return _instance; } } 
    
    // make the flag volatile 
    private static volatile bool s_initialized = false; 
    private static object s_lock = new object(); 
    
    
    // you still need to synchronize when you're initializing 
    public void Initialize() { 
        lock(s_lock) 
        { 
         if (!s_initialized) 
         { 
          // initialize 
    
           s_initialized = true; 
          } 
         } 
        } 
    } 
    

Там нет разногласий по структурированной карте, поэтому его безопасность потока не кажется скомпрометированы ...

Одноэлементный класс у вас не поточно. Главное помнить, что один экземпляр не гарантирует, что ни один поток может получить к нему доступ. Если есть несколько потоков, которые имеют ссылку на экземпляр, то на экземпляр и хранящиеся данные есть конкуренция. Если есть разногласия, вы должны обеспечить безопасность потока (синхронизировать как минимум).

+0

@ Lirik - отличная благодарность. Какие из этих предложений будут применяться при использовании структуры структуры для получения экземпляра? –

+0

@Ben Вы инициализируете экземпляр каждый раз, когда получаете его из структурированной карты? Получаете ли вы доступ к структурированной карте из нескольких потоков, чтобы получить экземпляры? – Kiril

+0

@Lirik - это была моя точка на самом деле. StructureMap имеет метод AsSingletons для маркировки экземпляра как одноэлементного. Я хотел бы знать, будет ли это предлагать ту же безопасность потоков, что и у меня с жестко закодированным синглом (в дополнение к вашим предложениям). –

Смежные вопросы