using System.Collections.Generic;
using System.Threading;

namespace CSharpUtilHelpV2
{
    /// <summary>
    /// 基于.NET 2.0的对于Dictionary线程安全操作工具类
    /// 说明
    /// 默认读锁超时1000毫秒
    /// 默认写锁超时1000毫秒
    /// .NET 4.0 可以使用ConcurrentDictionary来实现。
    /// </summary>
    /// <typeparam name="T">泛型</typeparam>
    public class ThreadSafeDictionaryV2<T>
    {
        /*参考资料
         * 1.
         * 使用Monitor或Mutex进行同步控制的问题:由于独占访问模型不允许任何形式的并发访问,这样的效率总是不太高。
         * 许多时候,应用程序在访问资源时是进行读操作,写操作相对较少。为解决这一问题,
         * C#提供了System.Threading.ReaderWriterLock类以适应多用户读/单用户写的场景。该类可实现以下功能:
         * 如果资源未被写操作锁定,那么任何线程都可对该资源进行读操作锁定,并且对读操作锁数量没有限制,即多个线程可同时对该资源进行读操作锁定,以读取数据。
         * 如果资源未被添加任何读或写操作锁,那么一个且仅有一个线程可对该资源添加写操作锁定,以写入数据。简单的讲就是:读操作锁是共享锁,允许多个线程同时读取数据;
         * 写操作锁是独占锁,同一时刻,仅允许一个线程进行写操作。
         * 引用链接:http://www.csharpwin.com/dotnetspace/12761r5814.shtml
         *
         * 2.
         * ReaderWriterLock 用于同步对资源的访问。在任一特定时刻,它允许多个线程同时进行读访问,或者允许单个线程进行写访问。
         * 在资源不经常发生更改的情况下,ReaderWriterLock 所提供的吞吐量比简单的一次只允许一个线程的锁(如 Monitor)更高。
         * 在多数访问为读访问,而写访问频率较低、持续时间也比较短的情况下,ReaderWriterLock 的性能最好。
         * 多个读线程与单个写线程交替进行操作,所以读线程和写线程都不会长时间阻止。
         * 大多数在 ReaderWriterLock 上获取锁的方法都采用超时值。使用超时可以避免应用程序中出现死锁。
         * 如果不使用超时,这两个线程将出现死锁。
         * 引用链接:http://msdn.microsoft.com/zh-cn/library/system.threading.readerwriterlock(v=vs.80).aspx
         *
         * 3.其他链接
         * http://tinythreadsafecache.codeplex.com/SourceControl/latest#TinyThreadSafeCache.cs
         * http://www.grumpydev.com/2010/02/25/thread-safe-dictionarytkeytvalue/
         * http://stackoverflow.com/questions/157933/whats-the-best-way-of-implementing-a-thread-safe-dictionary
         * http://stackoverflow.com/questions/15095817/adding-to-a-generic-dictionary-causes-indexoutofrangeexception
         */

        ReaderWriterLock rwlock = new ReaderWriterLock();//声明读写锁 .NET 3.5+ 推荐用ReaderWriterLockSlim
        Dictionary<string, T> dic = new Dictionary<string, T>();//Dictionary
        static int readerTimeout = 1000;//默认读锁超时1000毫秒
        static int writerTimeout = 1000;//默认写锁超时1000毫秒
        /// <summary>
        /// 默认构造函数
        /// </summary>
        public ThreadSafeDictionaryV2()
        {

        }
        /// <summary>
        /// 带参构造函数
        /// </summary>
        /// <param name="_readerTimeout">读锁超时设置【单位毫秒】</param>
        /// <param name="_writerTimeout">写锁超时设置【单位毫秒】</param>
        public ThreadSafeDictionaryV2(int _readerTimeout, int _writerTimeout)
        {
            readerTimeout = _readerTimeout;
            writerTimeout = _writerTimeout;
        }
        /// <summary>
        /// This【线程安全】
        /// </summary>
        /// <param name="key">键</param>
        /// <returns>值</returns>
        public T this[string key]
        {
            get
            {
                rwlock.AcquireReaderLock(readerTimeout);
                try
                {
                    return dic[key];
                }
                finally
                {
                    rwlock.ReleaseReaderLock();
                }
            }
            set
            {
                rwlock.AcquireWriterLock(writerTimeout);
                try
                {
                    dic[key] = value;
                }
                finally
                {
                    rwlock.ReleaseWriterLock();
                }
            }
        }

        /// <summary>
        /// Add【线程安全】
        /// 默认超时1000毫秒
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="val">值</param>
        public void Add(string key, T val)
        {
            Add(key, val, writerTimeout);
        }
        /// <summary>
        /// Add【线程安全】
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="val">值</param>
        /// <param name="timeout">超时设置【毫秒】</param>
        public void Add(string key, T val, int timeout)
        {
            rwlock.AcquireWriterLock(timeout);
            try
            {
                dic[key] = val;
            }
            finally
            {
                rwlock.ReleaseWriterLock();
            }
        }
        /// <summary>
        /// Get【线程安全】
        /// 默认超时1000毫秒
        /// </summary>
        /// <param name="key">键</param>
        /// <returns>值</returns>
        public T Get(string key)
        {
            return Get(key, readerTimeout);
        }
        /// <summary>
        /// Get【线程安全】
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="timeout">超时设置【毫秒】</param>
        /// <returns>值</returns>
        public T Get(string key, int timeout)
        {
            rwlock.AcquireReaderLock(timeout);
            try
            {
                T val;
                dic.TryGetValue(key, out val);
                return val;
            }
            finally
            {
                rwlock.ReleaseReaderLock();
            }
        }
        /// <summary>
        /// Remove【线程安全】
        /// 默认超时1000毫秒
        /// </summary>
        /// <param name="key">键</param>
        public void Remove(string key)
        {
            Remove(key, writerTimeout);
        }
        /// <summary>
        /// Remove【线程安全】
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="timeout">超时设置【毫秒】</param>
        public void Remove(string key, int timeout)
        {
            rwlock.AcquireWriterLock(timeout);
            try
            {
                dic.Remove(key);
            }
            finally
            {
                rwlock.ReleaseWriterLock();
            }
        }
        /// <summary>
        /// Clear【线程安全】
        /// 默认超时1000毫秒
        /// </summary>
        public void Clear()
        {
            Clear(writerTimeout);
        }
        /// <summary>
        /// Clear【线程安全】
        /// </summary>
        /// <param name="timeout">超时设置【毫秒】</param>
        public void Clear(int timeout)
        {
            rwlock.AcquireWriterLock(timeout);
            try
            {
                dic.Clear();
            }
            finally
            {
                rwlock.ReleaseWriterLock();
            }
        }
        /// <summary>
        /// ContainsKey【线程安全】
        /// 默认超时1000毫秒
        /// </summary>
        /// <param name="key">键</param>
        /// <returns>是否包含</returns>
        public bool ContainsKey(string key)
        {
            return ContainsKey(key, readerTimeout);
        }
        /// <summary>
        /// ContainsKey【线程安全】
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="timeout">超时设置【毫秒】</param>
        /// <returns>是否包含</returns>
        public bool ContainsKey(string key, int timeout)
        {
            rwlock.AcquireReaderLock(timeout);
            try
            {
                return dic.ContainsKey(key);
            }
            finally
            {
                rwlock.ReleaseReaderLock();
            }
        }
        /// <summary>
        /// Count【线程安全】
        /// 默认超时1000毫秒
        /// </summary>
        /// <returns></returns>
        public int Count()
        {
            return Count(readerTimeout);
        }
        /// <summary>
        /// Count【线程安全】
        /// </summary>
        /// <param name="timeout">超时设置【毫秒】</param>
        /// <returns>Count</returns>
        public int Count(int timeout)
        {
            rwlock.AcquireReaderLock(timeout);
            try
            {
                return dic.Count;
            }
            finally
            {
                rwlock.ReleaseReaderLock();
            }
        }
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

[C#]Thread Safe Dictionary in .NET 2.0的更多相关文章

  1. 【转】php Thread Safe(线程安全)和None Thread Safe(NTS,非 线程安全)之分

    Windows版的PHP从版本5.2.1开始有Thread Safe(线程安全)和None Thread Safe(NTS,非线程安全)之分,这两者不同在于何处?到底应该用哪种?这里做一个简单的介绍. ...

  2. PHP版本VC6与VC9、Thread Safe与None-Thread Safe等的区别

    PHP版本VC6与VC9.Thread Safe与None-Thread Safe等的区别 [摘要]PHP 是一种 HTML 内嵌式的语言,是一种在服务器端执行的嵌入HTML文档的脚本语言,在PHP发 ...

  3. Thread Safe(线程安全)和None Thread Safe(NTS,非线程安全)之分

    Windows版的PHP从版本5.2.1开始有Thread Safe(线程安全)和None Thread Safe(NTS,非线程安全)之分,这两者不同在于何处?到底应该用哪种?这里做一个简单的介绍. ...

  4. PHP的(Thread Safe与Non Thread Safe)

    在安装xdebug到时候你会有有TS和NTS版本的选择,在以前还有VC6和VC9的版本.如果你没有根据你目前的服务器的状况选择对应的版本的话,那么xdebug是安装不成功的. 一.如何选择 php5. ...

  5. PHP版本VC6与VC9/VC11/VC14、Thread Safe与None-Thread Safe等的区别

    最近正好在弄一个PHP的程序,在这之前一直没有怎么以接触,发现对PHP版本知识了解不是很清楚,自己看了不少类似的文章,还是感觉不够明确和全面, 网上的结论又都是模棱两可,在此,给出最完整甚至武断的解释 ...

  6. windows zend_guard+apache no ssl+php no Thread Safe fastcgi模式 环境配置

    最近公司要做代码加密,就采用ZEND GUARD 方式加密代码 并进行显示 此文为总结,以备自己以后查看和给需要的同学们参考 采用的php为5.3版本  由于现在加密的更改, 能支持zend guar ...

  7. PHP关于VC9和VC6以及Thread Safe和Non Thread Safe版本选择的问题

    一.如何选择PHP5.3的VC9版本和VC6版本 VC6版本是使用Visual Studio 6编译器编译的,如果你的PHP是用Apache来架设的,那你就选择VC6版本.      VC9版本是使用 ...

  8. PHP关于VC11,VC9,VC6以及Thread Safe和Non Thread Safe版本选择的问题

    这里是我在搭建php环境时收集的资料供大家参考: 现在PHP官网上下载PHP安装包都有VC11或VC9的字样,这是什么含义,我们应该下载哪种安装包更好呢?其实PHP官网给出了答案: VC6版本是使用V ...

  9. PHP版本VC6和VC9、Non Thread Safe和Thread Safe的区别

    链接:http://www.cnblogs.com/neve/articles/1863853.html 想更新个PHP的版本,PHP的windows版本已经分离出来了,见http://windows ...

随机推荐

  1. Spring源码入门——DefaultBeanNameGenerator解析

    我们知道在spring中每个bean都要有一个id或者name标示每个唯一的bean,在xml中定义一个bean可以指定其id和name值,但那些没有指定的,或者注解的spring的beanname怎 ...

  2. java+数据库+D3.js 实时查询人物关系图

    先看下 效果 某个用户,邀请了自己的朋友 ,自己的朋友邀请了其他朋友,1 展示邀请关系,2 点击头像显示邀请人和被邀请人的关系.(网上这种资料很少, 另外很多都是从JSON文件取 数据, 这里是从数据 ...

  3. Cactus借助Jetty测试Servlet

    这是一个WebProject,但不需要web.xml,因为用不到它 首先是待测试的LoginServlet.java package com.jadyer.servlet; import java.i ...

  4. jQuery EasyUI, datagrid, treegrid formatter 参数比较 row index

    如题: datagrid中,见官方文档: formatter function The cell formatter function, take three parameter:value: the ...

  5. poj 3253 Fence Repair(优先队列+哈夫曼树)

    题目地址:POJ 3253 哈夫曼树的结构就是一个二叉树,每个父节点都是两个子节点的和. 这个题就是能够从子节点向根节点推. 每次选择两个最小的进行合并.将合并后的值继续加进优先队列中.直至还剩下一个 ...

  6. map的例子

    11.4 编写单词计数程序,忽略大小写和标点.例如,“example.”,“example,"和”Example“应该递增相同的计算器. #include<iostream> # ...

  7. PureMVC(JS版)源码解析:总结

    PureMVC源码中设计到的11个类已经全部解析完了,回首想想,花了一周的时间做的这点事情还是挺值得的,自己的文字组织表达能力和对pureMVC的理解也在写博客的过程中得到了些提升.我也是第一次写系列 ...

  8. Android 自定义View修炼-【2014年最后的分享啦】Android实现自定义刮刮卡效果View

    一.简介: 今天是2014年最后一天啦,首先在这里,我祝福大家在新的2015年都一个个的新健康,新收入,新顺利,新如意!!! 上一偏,我介绍了用Xfermode实现自定义圆角和椭圆图片view的博文& ...

  9. vi快捷键必知必会

    文本编辑器是所有计算机系统中最常用的一种工具.UNIX下的编辑器有ex,sed和vi等,其中,使用最为广泛的是vi,而vi命令繁多,论坛里好像这方面的总结不多,以下稍做总结,以资共享!渴望更正和补充! ...

  10. kali2.0如何安装中文输入法

    由于kali的更新源是国外网站,替换成国内的镜像站,具体操作如下: 打开终端输入 leafpad /etc/apt/sources.list   把下面的源粘贴进去,原有内容注释掉 #中科大源deb  ...