编程语言
首页 > 编程语言> > c#-Structuremap单例线程安全吗?

c#-Structuremap单例线程安全吗?

作者:互联网

目前我有以下课程:

    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和结构映射来初始化我的服务,因此我进行了如下重构:

    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();

这可以按预期工作(在以下代码中,单子返回true):

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

        bool singleton = (instance1 == instance2);

因此,我的下一个问题是结构映射解决方案是否像单例类一样安全.唯一的缺点是,这仍将允许直接实例化NewPluginService(如果不使用结构映射).

非常感谢,

解决方法:

我会提出一些建议:

>布尔标志应该是可变的
>将您的单例实例设为只读
>初始化不是线程安全的,无论您只有一个实例是事实…因此都应该同步

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

结构化映射上没有争用,因此它的线程安全性似乎没有受到损害.

您拥有的单例类不是线程安全的.要记住的主要事情是,单个实例并不能确保单个线程只能访问它.如果有多个线程引用该实例,则该实例及其所持有的数据存在争用.如果存在争用,则应确保线程安全(至少同步).

标签:thread-safety,singleton,structuremap,c
来源: https://codeday.me/bug/20191210/2099746.html