如何使单身成员线程安全

时间:2015-10-25 12:31:33

标签: c# multithreading singleton

我们说我有以下单身人士:

public sealed class singleton
{
// fields, creation, etc.
private static IList<SomeObjectType> _objects = new List<SomeObjectType>();
private ManualResetEvent _updateCompleted = new ManualResetEvent(true);

private bool RefreshRequired()
{
    //true if records in DB newer than the objects in the list
}

private void RefreshList()
{
    _updateCompleted.Reset();

    //code to refresh the list

    _updateCompleted.Set();
}

public IList<SomeObjectType> Objects
{
    get
    {
        _updateCompleted.Wait();

        if (RefreshRequired())
            RefreshList();

        return _objects;
    }
}

..

这样我试图实现存储在列表中的数据在任何客户端读取之前始终是最新的。这种机制非常简单,但到目前为止它运作良好。但是,显然它对于多线程场景来说还不够。 如果有多个线程访问Objects-Member,我只希望第一个线程检查数据是否是最新的,然后在必要时更新List。在刷新过程中,所有其他线程应该被强制等待,甚至检查是否需要刷新。 我已经阅读了很多ablut锁,BlockedCollections和ManualResetEvents,但我不确定使用哪个概念。

你能解释一下你会选择哪一个以及如何解决所描述的任务吗?

1 个答案:

答案 0 :(得分:-1)

我建议的最佳答案可在此处找到:http://csharpindepth.com/Articles/General/Singleton.aspx

如果只是张贴链接,我会被群众大吼大叫,这里有一些从文章中抽取的样本进行思考。这篇文章主要与性能和适当性有关,所以请阅读这些样本的描述。

就您的刷新方法而言,其他人对此评论相当不错。了解它的消费方式同样重要。

希望这篇文章能给你一些思考的东西。

简单的线程安全......

public sealed class Singleton
{
    private static Singleton instance = null;
    private static readonly object padlock = new object();

    Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            lock (padlock)
            {
                if (instance == null)
                {
                    instance = new Singleton();
                }
                return instance;
            }
        }
    }
}

不使用锁的线程安全......

public sealed class Singleton
{
    private static readonly Singleton instance = new Singleton();

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static Singleton()
    {
    }

    private Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            return instance;
        }
    }
}

完全懒惰的实例化......

public sealed class Singleton
{
    private Singleton()
    {
    }

    public static Singleton Instance { get { return Nested.instance; } }

    private class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested()
        {
        }

        internal static readonly Singleton instance = new Singleton();
    }
}

使用.NET 4的Lazy类型......

public sealed class Singleton
{
    private static readonly Lazy<Singleton> lazy =
        new Lazy<Singleton>(() => new Singleton());

    public static Singleton Instance { get { return lazy.Value; } }

    private Singleton()
    {
    }
}