一个 .Net Hashtable 的锁的疑惑和解决
今天同事告诉我, 锁 hashtable 应该锁它的 SyncRoot 属性而不应该锁它的实例, 例如:
Hashtable ht = new Hashtable();
lock(ht.SyncRoot)
{
...
}
看了 .Net Framework 文档, 给的例子也是锁 SyncRoot 属性, 说如果锁实例的话不能保证在并发情况下的同步, 我很疑惑, 为什么不能锁 hashtable 实例本身呢?
做了个实验, 两个线程 A 和 B, 用锁实例和锁 SyncRoot 两种方式测试, 都没有问题, 结果是一样的。
后来, 用 Hashtable.Synchronized 创建自动线程同步的 hashtable, 终于明白了 SyncRoot 的作用。先说说自动线程同步的 Hashtable: 如果 Hashtable 要允许并发读但只能一个线程写, 要这么创建 Hashtable 实例:
Hashtable hashtable = Hashtable.Synchronized(new Hashtable());
这样, 如果有多个线程并发的企图写 hashtable 里面的 item, 则同一时刻只能有一个线程写, 其余阻塞; 对读的线程则不受影响。
测试的代码是这样的:
Hashtable _hashtable = Hashtable.Synchronized(new Hashtable());
public void TestLock()
{
Thread t1 = new Thread(new ThreadStart(SyncFunctionA));
Thread t2 = new Thread(new ThreadStart(SyncFunctionB));
t1.Start();
t2.Start();
Thread.Sleep(8000);
Console.WriteLine("hashtable[" + _key_a + "] = " + _hashtable[_key_a]);
}
private void SyncFunctionA()
{
lock (_hashtable.SyncRoot)
{
Thread.Sleep(5000);
_hashtable[_key_a] = "Value set by SyncFunctionA";
}
}
private void SyncFunctionB()
{
Console.WriteLine("hashtable[" + _key_a + "] = " + _hashtable[_key_a]);
_hashtable[_key_a] = "Value set by SyncFunctionB";
}
为了清楚的看到效果, 线程 A 用了锁, 并睡眠 5 秒, 睡醒后设置一下 hashtable 里的 item. 线程 B 先读一下 hashtable 里的 item, 再写 hashtable 里的 item。因为对 SyncRoot 加了锁, 即使线程 B 没有显式的对 hashtable 加锁, 但在 _hashtable[_key_a] = "Value set by SyncFunctionB" 一句上也会被 hashtable 自动锁住, 直到线程 A 释放掉 SyncRoot 锁为止。如果线程 A 不是锁 SyncRoot 而是锁 hashtable 实例本身, 那么线程 B 不会在 _hashtable[_key_a] = "Value set by SyncFunctionB" 上被自动锁住。
所以, 总结如下:
如果想锁整个 hashtable, 包括读和写, 即不允许并发的读和写, 那应该锁 hashtable 实例;
如果想允许并发的读, 不允许并发的写, 那应该创建 Synchronized 的 hashtable, 并对要加锁的一块代码用 SyncRoot 锁住, 如果不需要对一块代码加锁, 则 hashtable 会自动对单个写的操作加锁。
转载于:https://www.cnblogs.com/hyfei0315/articles/1238627.html
一个 .Net Hashtable 的锁的疑惑和解决相关推荐
- 从0设计一个基于Redis的锁服务
作者:温灏,后端研发,专注于Python和Go,对分布式系统感兴趣,本文系作者投稿,有兴趣投稿的同学,请后台回复[投稿] 由于微服务大行其道,服务之间的协调工作变得越来越重要.今天来简单说一下如何搭建 ...
- 深入Lock锁底层原理实现,手写一个可重入锁
synchronized与lock lock是一个接口,而synchronized是在JVM层面实现的.synchronized释放锁有两种方式: 获取锁的线程执行完同步代码,释放锁 . 线程执行发生 ...
- 【设置一个类似手机的锁屏界面但又不知道如何操作——下载加速吧】
对于很多公共办公场所来说,经常会需求临时离开一会,比如去喝水或者上厕所.如果这个时候,我们希望电脑上的东西部被他们动到或者看到该怎么办呢?这是今日有网友问到的一个类似问题,网友希望在离开的时候,可以设 ...
- 一个多线程死锁案例,如何避免及解决死锁问题
转载自 一个多线程死锁案例,如何避免及解决死锁问题 多线程死锁在java程序员笔试的时候时有遇见,死锁概念在之前的文章有介绍,大家应该也都明白它的概念,不清楚的去翻看历史文章吧. 下面是一个多线程死锁 ...
- mysql锁表原因及解决
mysql锁表原因及解决 问题如图 锁表发生原因 锁表发生在 insert.update.delete中: 锁表的原理是数据库使用独占式锁机制,当执行上面的语句时,对表进行锁住,直到发生commit或 ...
- MySQL--死锁的原因及解决方法
原文网址:MySQL--死锁的原因及解决方法_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍MySQL死锁的原因及解决方法. InnoDB中,除单个SQL组成的事务外,锁是逐步获得的,所以可能 ...
- 如何解除计算机方向键问题,笔记本键盘上下左右键怎么解锁_笔记本电脑的上下左右键被锁住了如何解决-win7之家...
我们在电脑中玩游戏的时候,经常会使用到键盘上下左右键来进行操作,不过有不少笔记本用户反映说键盘上下左右键被锁住了,导致无法操作,但是这种情况不多见,如果被锁定的话.一般是数字区域,方向键基本上没有被锁 ...
- Python GIL锁问题探究及解决
1. 什么是GIL? GIL即全局解释器(global interpreter lock).python的每个线程在执行时都需要先获取GIL,保证同一时刻只有一个线程可以执行代码,即同一时刻只有持有G ...
- python gil 解除_详解Python中的GIL(全局解释器锁)详解及解决GIL的几种方案
先看一道GIL面试题: 描述Python GIL的概念, 以及它对python多线程的影响?编写一个多线程抓取网页的程序,并阐明多线程抓取程序是否可比单线程性能有提升,并解释原因. GIL:又叫全局解 ...
最新文章
- 已知环境静态障碍物避障_我女儿如何教我无障碍环境
- IBM推出127量子比特处理器,超越谷歌和中科大
- Spark编程模型几大要素
- C#.Net工作笔记003---异步编程async await_在开发中的使用经验_随时更新
- caffe安装_【开源框架】caffe图像分类从模型自定义到测试
- paip.Adblock屏蔽onlinedown华军软件园的4秒下载广告总结..
- ad18 bell封装_Altium 中异形焊盘异形封装的创建图文教程
- 虎牙直播Js说书人弹幕
- SQL Server表空间碎片化回收
- 50 岁的程序员该何去何从?
- 免企业资质免签约支付
- 图论(九)有向图和网络
- 一种高效的q+1准均匀量化(quasi-uniform quantization)方法及MATLAB实现
- Nature Cell Biology:揭示 PI3K-Akt 信号通路新机制,有望成为癌症治疗新靶点
- 八招教你解决网络故障!
- Linux 入门视频教程
- 机架服务器和群晖存文件对比,如何选购群晖nas网络存储服务器?
- python比较日期时间_python时间如何比较
- Qt Creator不同Qt版本切换
- layui 表格隐藏id列