线程安全Dictionary

public abstract class ReadFreeCache<TKey, TValue>
{
    protected ReadFreeCache()
        : this(null)
    { }

    protected ReadFreeCache(IEqualityComparer<TKey> comparer)
    {
        this.m_storage = new Dictionary<TKey, TValue>(comparer);
    }

    public abstract TValue Create(TKey key);

    private Dictionary<TKey, TValue> m_storage;
    private readonly object m_writeLock = new object();
    
    public TValue Get(TKey key)
    {
        TValue value;

        if (this.m_storage.TryGetValue(key, out value))
        {
            return value;
        }

        lock (this.m_writeLock)
        {
            if (this.m_storage.TryGetValue(key, out value))
            {
                return value;
            }

            value = this.Create(key);
            var newStorage = this.m_storage.ToDictionary(
                p => p.Key,
                p => p.Value,
                this.m_storage.Comparer);

            newStorage.Add(key, value);
            this.m_storage = newStorage;
        }

        return value;
    }
}
public abstract class ReadWriteCache<TKey, TValue>
{
    protected ReadWriteCache()
        : this(null)
    { }

    protected ReadWriteCache(IEqualityComparer<TKey> comparer)
    {
        this.m_storage = new Dictionary<TKey, TValue>(comparer);
    }

    private readonly Dictionary<TKey, TValue> m_storage;
    private readonly ReaderWriterLockSlim m_rwLock = new ReaderWriterLockSlim();

    protected abstract TValue Create(TKey key);

    public TValue Get(TKey key)
    {
        TValue value;

        this.m_rwLock.EnterReadLock();
        try
        {
            if (this.m_storage.TryGetValue(key, out value))
            {
                return value;
            }
        }
        finally
        {
            this.m_rwLock.ExitReadLock();
        }

        this.m_rwLock.EnterWriteLock();
        try
        {
            if (this.m_storage.TryGetValue(key, out value))
            {
                return value;
            }

            value = this.Create(key);
            this.m_storage.Add(key, value);
        }
        finally
        {
            this.m_rwLock.ExitWriteLock();
        }

        return value;
    }
}

 

posted @ 2015-12-24 17:49  BG  阅读(225)  评论(0编辑  收藏  举报