Is singleton thread structure safe?

I currently have the following class:

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

The important thing is that Initialize () should be executed only once while the application is running. I thought I was reorganizing this into a singleton class, since that would be more thread safe ?:

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

The only question is whether it is necessary to have a lock here (I deleted it), since we will work only in one instance?

Finally, I want to use DI and the structural map to initialize my servlets, so I reworked like this:

    public interface IPluginService {
    void Initialize();
}

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

            s_initialized = true;
        }
    }
}

And in my registry:

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

This works as expected (singleton returns true in the following code):

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

        bool singleton = (instance1 == instance2);

, - , singleton ( ). , NewPluginService ( ).

,

+3
1

:

  • volatile
  • singleton 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;
                }
            }
        }
    }
    

, ...

singleton, , . , , . , , , . , ( ).

+3

Source: https://habr.com/ru/post/1738639/


All Articles