基础知识重要吗?真的很重要。
就在笔者与同事聊天中突然同事提出一个问题,让笔都有点乱了手脚(有点夸张),题目是这样的:
问: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 实现并发情况下,既有读线程,又有写线程的线程安全实例:

 private Hashtable _ht = Hashtable.Synchronized(new Hashtable());
static void Main(string[] args)
{
new Program().TestLock();
Console.WriteLine($"主线程:{Thread.CurrentThread.ManagedThreadId}");
Console.ReadKey();
} public void TestLock()
{
Task.Factory.StartNew(obj => SyncMethodA((string)obj), "laowang");
Task.Factory.StartNew(obj => SyncMethodB((string)obj), "liupangzi");
Thread.Sleep();
Console.WriteLine($"输出值:{ _ht[0]}");
} private void SyncMethodA(string param)
{
Console.WriteLine($"方法A线程:{Thread.CurrentThread.ManagedThreadId}");
lock (_ht.SyncRoot)
{
Thread.Sleep();
_ht[] = "SyncMethodA";
Console.WriteLine($"A方法输出值:{ _ht[0]}");
}
} private void SyncMethodB(string param)
{
Console.WriteLine($"方法B线程:{Thread.CurrentThread.ManagedThreadId}");
Console.WriteLine($"B方法输出值:{ _ht[0]}");
_ht[] = "SyncMethodB";
}
 
     为了看到效果,线程A使用了锁,并睡眠 5 秒,后设置 hashtable 值为 SyncMethodA ,线程B先读取 hashtable 中的值,再写入 SyncMethodB 值到 hashtable 中。在写入值这句上会被 hashtable 自动销锁住 ,直到A释放掉 SyncRoot 为止。
     上面代码中我们实现锁 SyncRoot 方式进行测试,结果:
     
   如果我们更改锁的对象为 hashtable 实例本身,lock(_ht) ,那么线程B不会在 hashtable="SyncMethodB" 这句话自动锁住。所以输出值是:SyncMethodA
注:以上代码请忽略方法传值      
        
    

C# 集合 — Hashtable 线程安全的更多相关文章

  1. C# Synchronized 和 SyncRoot 实现线程同步的源码分析及泛型集合的线程安全访问

    转载:http://blog.csdn.net/zztfj/article/details/5640889 Synchronized vs SyncRoot 我们知道,在.net的一些集合类型中,譬如 ...

  2. [转帖]C#中字典集合HashTable、Dictionary、ConcurrentDictionary三者区别

    C#中字典集合HashTable.Dictionary.ConcurrentDictionary三者区别 https://blog.csdn.net/yinghuolsx/article/detail ...

  3. Java中的集合和线程安全

    通过Java指南我们知道Java集合框架(Collection Framework)如何为并发服务,我们应该如何在单线程和多线程中使用集合(Collection). 话题有点高端,我们不是很好理解.所 ...

  4. 通过Collections将集合转换为线程安全类集合

    通过Collections将集合转换为线程安全类集合 List集合: List<String> list=new ArrayList<String>();list.add(&q ...

  5. 编写高质量代码改善C#程序的157个建议——建议22:确保集合的线程安全

    建议22:确保集合的线程安全 集合线程安全是指多个线程上添加或删除元素时,线程键必须保持同步. 下面代码模拟了一个线程在迭代过程中,另一个线程对元素进行了删除. class Program { sta ...

  6. Vector、HashTable线程不安全示例

    下面这样写法是Vector线程不安全的写法: import java.util.Vector; public class Test { private static Vector<Integer ...

  7. Java并发编程之set集合的线程安全类你知道吗

    Java并发编程之-set集合的线程安全类 Java中set集合怎么保证线程安全,这种方式你知道吗? 在Java中set集合是 本篇是<凯哥(凯哥Java:kagejava)并发编程学习> ...

  8. Day10_53_Collections.synchronizedList() 将Arraylist集合转换为线程安全的集合

    将Arraylist集合转换为线程安全的集合 import java.util.ArrayList; import java.util.Collections; import java.util.Li ...

  9. C#中字典集合HashTable、Dictionary、ConcurrentDictionary三者区别

    C#中HashTable.Dictionary.ConcurrentDictionar三者都表示键/值对的集合,但是到底有什么区别,下面详细介绍 一.HashTable HashTable表示键/值对 ...

随机推荐

  1. 查看oracle SID

    源地址:http://blog.sina.com.cn/s/blog_5f20c4740100dodl.html SID就是数据库的实例 select instance_name from  V$in ...

  2. JAVASE 打印输出--------01

    public class Demo01 { public String a1; public int a2; public Demo01(String a, int i) { a1 = a; a2 = ...

  3. [Flex] as3xls读取excel,修改保存单表(二)

    这个方法仅用了as3xls读取excel的功能,修改保存独立出来了. <?xml version="1.0" encoding="utf-8"?> ...

  4. editplus格式化xml文档

    使用editplus打开xml文档,发现文件内容没有格式化,非常难看,使用IE9打开这个xml文档是格式化的,但是IE9打开不能编辑. 在网上找了一些资料发现能够通过一个小插件来是editplus格式 ...

  5. golang.org/x/mobile/exp/gl/glutil/glimage.go 源码分析

    看这篇之前,建议先看之前几篇,这几篇是基础. Go Mobile 例子 basic 源码分析 http://www.cnblogs.com/ghj1976/p/5183199.html OpenGL ...

  6. lambda表达式、内置函数、进制和文件操作

    lambda表达式 定义函数(普通方式)def f1(): return 123 f2 = lambda : 123 def f3(a1,a2): return a1+a2 定义函数(lambda表达 ...

  7. Mingyang.net:自定义FreeMarkerView

    自定义FreeMarkerView的目的是为了放一些公共的变量到FreeMarker模版里面.spring-context.xml: <!-- ************************* ...

  8. SELinux配置不当导致httpd无法在非80端口启动

    检测是否为selinux导致httpd启动失败,若setenforce 0以后就可以启动,就表示selinux配置不当. 首先本机要支持semanage命令,安装方法网上有. semanage  po ...

  9. [ZOJ 3662] Math Magic (动态规划+状态压缩)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3662 之前写过这道题,结果被康神吐槽说代码写的挫. 的确,那时候 ...

  10. WIN7上搭建Windows Phone 8 开发环境——VMware Workstation下Win8 “无法安装Hyper-V, 某个虚拟机监控程序正在运行”问题解决的办法

    最近在试着在Windows 7上搭建Windows Phone 8的开发调试环境,使用的是VMware Workstation + Win8 Pro的虚拟环境, 在漫长的WPexpress_full下 ...