博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 集合 — Hashtable 线程安全
阅读量:6268 次
发布时间:2019-06-22

本文共 2197 字,大约阅读时间需要 7 分钟。

基础知识重要吗?真的很重要。
就在笔者与同事聊天中突然同事提出一个问题,让笔都有点乱了手脚(有点夸张),题目是这样的:
问:Hashtable 是线程安全的吗?
答:…… (沉默中,Yes Or No?Why?)
 
带着问题我们一步一步的解答:
1、线程安全
    
 概念: 通俗的讲就是多线程访问时,采用了加锁机制,当一个线程操作临界区时,对临界区进行保护,其他线程等前面线程操作完才能排队操作临界区。这样保障数据一致减少数据污染。
2、求证
    
 各种资料显示 Hashtable 的 Synchronized 静态方法提供线程安全。那根据资料信息我们找到源代码,找到 Synchronized 是如何提供线程安全的。
     都知道 Hashtable 来自 System.Collections 那我们就从他着手找到 Hashtable 中的静态方法 Synchronized:
     
    
 从源码中可以看出,Synchronized 返回一个 SyncHashtable 实例。我们接着找 SyncHashtable
     SyncHashtable 继承自 Hashtable,之所以实现线程安全操作,因为 SyncHashtable 中就已经增加 lock 、
     
3、结论
    到这里至少能证明 Hashtable 在实现静 Synchroinzed 方法时是线程安全的没错吧!
    下面写个实例来说明如何使用 Synchronized 实现并发情况下,既有读线程,又有写线程的线程安全实例:
    
1 private Hashtable _ht = Hashtable.Synchronized(new Hashtable()); 2         static void Main(string[] args) 3         { 4             new Program().TestLock(); 5             Console.WriteLine($"主线程:{Thread.CurrentThread.ManagedThreadId}"); 6             Console.ReadKey(); 7         } 8  9         public void TestLock()10         {11             Task.Factory.StartNew(obj => SyncMethodA((string)obj), "laowang");12             Task.Factory.StartNew(obj => SyncMethodB((string)obj), "liupangzi");13             Thread.Sleep(6000);14             Console.WriteLine($"输出值:{ _ht[0]}");15         }16 17 18         private void SyncMethodA(string param)19         {20             Console.WriteLine($"方法A线程:{Thread.CurrentThread.ManagedThreadId}");21             lock (_ht.SyncRoot)22             {23                 Thread.Sleep(5000);24                 _ht[0] = "SyncMethodA";25                 Console.WriteLine($"A方法输出值:{ _ht[0]}");26             }27         }28 29         private void SyncMethodB(string param)30         {31             Console.WriteLine($"方法B线程:{Thread.CurrentThread.ManagedThreadId}");32             Console.WriteLine($"B方法输出值:{ _ht[0]}");33             _ht[0] = "SyncMethodB";34         }
View Code
 
     为了看到效果,线程A使用了锁,并睡眠 5 秒,后设置 hashtable 值为 SyncMethodA ,线程B先读取 hashtable 中的值,再写入 SyncMethodB 值到 hashtable 中。在写入值这句上会被 hashtable 自动销锁住 ,直到A释放掉 SyncRoot 为止。
     上面代码中我们实现锁 SyncRoot 方式进行测试,结果:
     
   
如果我们更改锁的对象为 hashtable 实例本身,lock(_ht) ,那么线程B不会在 hashtable="SyncMethodB" 这句话自动锁住。所以输出值是:SyncMethodA
注:以上代码请忽略方法传值
      
        
    

转载于:https://www.cnblogs.com/lanyuanbo/p/5857038.html

你可能感兴趣的文章
BBS论坛(二十七)
查看>>
html DOM 的继承关系
查看>>
装饰器的邪门歪道
查看>>
Dubbo常用配置解析
查看>>
【转】C#解析Json Newtonsoft.Json
查看>>
macports的安装及常用命令
查看>>
(转)使用C#开发ActiveX控件
查看>>
spring mvc 基于注解 配置默认 handlermapping
查看>>
半小时学会上传本地项目到github
查看>>
Android学Jni/Ndk 开发记录(一)
查看>>
Linux Tcl和Expect的安装
查看>>
WPF中的依赖项属性(转)
查看>>
linux防火墙相关 iptables
查看>>
最简单的单例模式
查看>>
JPopupMenu的使用以及JPopupMenu中子组件的事件处理
查看>>
从反汇编的角度看引用和指针的区别
查看>>
拓马长枪定乾坤
查看>>
UIProgressView的详细使用
查看>>
Silverlight实用窍门系列:70.Silverlight的视觉状态组VisualStateGroup
查看>>
照片筛选与上传功能
查看>>