c# Hashtable Synchronized vs SyncRoot
Synchronized vs SyncRoot 我们知道,在.net的一些集合类型中,譬如Hashtable和ArrayList,都有Synchronized静态方法和SyncRoot实例方法,他们之间有联系吗?我怎么才能用好他们呢?
我们以Hashtable为例,看看他们的基本用法:
Hashtable ht = Hashtable.Synchronized(new Hashtable());
lock (ht.SyncRoot)
{
//一些操作
}1,Synchronized表示返回一个线程安全的Hashtable,什么样的 hashtable才是一个线程安全的呢?下边我们就从.NET的源码开始理解。
public static Hashtable Synchronized(Hashtable table)
{
if (table == null)
{
throw new ArgumentNullException("table");
}
return new SyncHashtable(table);
}
从源码不难看出,Synchronized方法返回的其实是一个SynchHashtable类型的实例。在前边我们说过,Synchronized表示返回一个线程安全的Hashtable,从这个解释不难看出,SynchHashtable应该是继承自Hashtable。下边我们验证一下。看看 SynchHashtable类型的源码: Code
[Serializable]
private class SyncHashtable : Hashtable
{
// Fields
protected Hashtable _table;
// Methods
internal SyncHashtable(Hashtable table) : base(false)
{
this._table = table;
}
internal SyncHashtable(SerializationInfo info, StreamingContext context) : base(info, context)
{
this._table = (Hashtable) info.GetValue("ParentTable", typeof(Hashtable));
if (this._table == null)
{
throw new SerializationException(Environment.GetResourceString("Serialization_InsufficientState"));
}
}
public override void Add(object key, object value)
{
lock (this._table.SyncRoot)
{
this._table.Add(key, value);
}
}
public override void Clear()
{
lock (this._table.SyncRoot)
{
this._table.Clear();
}
}
public override object Clone()
{
lock (this._table.SyncRoot)
{
return Hashtable.Synchronized((Hashtable) this._table.Clone());
}
}
public override bool Contains(object key)
{
return this._table.Contains(key);
}
public override bool ContainsKey(object key)
{
return this._table.ContainsKey(key);
}
public override bool ContainsValue(object key)
{
lock (this._table.SyncRoot)
{
return this._table.ContainsValue(key);
}
}
public override void CopyTo(Array array, int arrayIndex)
{
lock (this._table.SyncRoot)
{
this._table.CopyTo(array, arrayIndex);
}
}
public override IDictionaryEnumerator GetEnumerator()
{
return this._table.GetEnumerator();
}
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
{
throw new ArgumentNullException("info");
}
info.AddValue("ParentTable", this._table, typeof(Hashtable));
}
public override void OnDeserialization(object sender)
{
}
public override void Remove(object key)
{
lock (this._table.SyncRoot)
{
this._table.Remove(key);
}
}
internal override KeyValuePairs[] ToKeyValuePairsArray()
{
return this._table.ToKeyValuePairsArray();
}
// Properties
public override int Count
{
get
{
return this._table.Count;
}
}
public override bool IsFixedSize
{
get
{
return this._table.IsFixedSize;
}
}
public override bool IsReadOnly
{
get
{
return this._table.IsReadOnly;
}
}
public override bool IsSynchronized
{
get
{
return true;
}
}
public override object this[object key]
{
get
{
return this._table[key];
}
set
{
lock (this._table.SyncRoot)
{
this._table[key] = value;
}
}
}
public override ICollection Keys
{
get
{
lock (this._table.SyncRoot)
{
return this._table.Keys;
}
}
}
public override object SyncRoot
{
get
{
return this._table.SyncRoot;
}
}
public override ICollection Values
{
get
{
lock (this._table.SyncRoot)
{
return this._table.Values;
}
}
}
}
Collapse Methods
呵呵,果然不出我们所料,SyncHashtable果然继承自Hashtable,SyncHashtable之所有能实现线程的安全操作,就是因为在他们的一些方法中,就加了lock,我们知道,哪一个线程执行了lock操作,在他还没有释放lock之前,其他线程都要处于堵塞状态。 SyncHashtable就是通过这种方法,来实现所谓的线程安全。
现在我们理解了Synchronized的含义和用法,那接下来我们看看他和SyncRoot之间的关系。
SyncRoot表示获取可用于同步 Hashtable 访问的对象,老实说,这个解释不好理解,要想真正理解他的用法,我们还得从源码开始: public virtual object SyncRoot
{
get
{
if (this._syncRoot == null)
{
Interlocked.CompareExchange(ref this._syncRoot, new object(), null);
}
return this._syncRoot;
}
}
如果您清楚Interlocked的用法,这段代码没什么难理解的了(不清楚的朋友找GOOGLE吧),Interlocked为多个线程共享的变量提供原子操作。原子操作就是单线程操作。在一个Hashtable实例中,不论我们在代码的任何位置调用,返回的都是同一个object类型的对象。我们在开始写的 lock(ht.SyncRoot)和下边的操作作用是一样的.
static object obj = new object();
lock(obj)
{
// 一些操作
}
他们之间不同的是,我们声明的static object类型对象是类型级别的,而SyncRoot是对象级别的。
通过上面的分析,我们都应该能理解Synchronized 和 SyncRoot用法,他们之间的关系就是:
Hashtable 通过Synchronized方法,生成一个SynchHashtable类型的对象,在这个对象的一个方法中,通过lock (this._table.SyncRoot)这样的代码来实现线程安全的操作,其中this._table.SyncRoot返回的就是一个 object类型的对象,在一个SynchHashtable对象实例中,不管我们调用多少次,他是唯一的。
c# Hashtable Synchronized vs SyncRoot的更多相关文章
- Synchronized vs SyncRoot
我们知道,在.net的一些集合类型中,譬如Hashtable和ArrayList,都有Synchronized静态方法和SyncRoot实例方法,他们之间有联系吗?我怎么才能用好他们呢?我们以Hash ...
- C# Synchronized 和 SyncRoot 实现线程同步的源码分析及泛型集合的线程安全访问
转载:http://blog.csdn.net/zztfj/article/details/5640889 Synchronized vs SyncRoot 我们知道,在.net的一些集合类型中,譬如 ...
- C#多线程编程之:集合类中Synchronized方法与SyncRoot属性原理分析
我们知道,在.net的一些集合类型中,譬如Hashtable和ArrayList,都有Synchronized静态方法和SyncRoot属性,他们之间有联系吗?我怎么才能用好他们呢? 以Hashtab ...
- C# 集合类 :(Array、 Arraylist、List、Hashtable、Dictionary、Stack、Queue)
我们用的比较多的非泛型集合类主要有 ArrayList类 和 HashTable类.我们经常用HashTable 来存储将要写入到数据库或者返回的信息,在这之间要不断的进行类型的转化,增加了系统装箱和 ...
- C# 集合 — Hashtable 线程安全
基础知识重要吗?真的很重要. 就在笔者与同事聊天中突然同事提出一个问题,让笔都有点乱了手脚(有点夸张),题目是这样的: 问:Hashtable 是线程安全的吗? 答:…… (沉默中,Yes Or No ...
- 类 Array Arraylist List Hashtable Dictionary
总结C# 集合类 Array Arraylist List Hashtable Dictionary Stack Queue 我们用的比较多的非泛型集合类主要有 ArrayList类 和 HashT ...
- C#的哈希表Hashtable同步方法
在多线程环境的操作中对Hashtable进行操作需要进行同步控制,有两种方法,一种是由.Net自动控制:一种是在代码中自己控制. 1.使用Hashtable.Synchronized进行同步 Hash ...
- C# 集合类 Array,Arraylist,List,Hashtable,Dictionary...
我们用的比较多的非泛型集合类主要有 ArrayList类 和 HashTable类.我们经常用HashTable 来存储将要写入到数据库或者返回的信息,在这之间要不断的进行类型的转化,增加了系统装箱和 ...
- [转]net中哈希表的使用 Hashtable
本文转自:http://www.cnblogs.com/gsk99/archive/2011/08/28/2155988.html 以下是PetShop中DBHelper中的使用过程: //创建哈希表 ...
随机推荐
- Android开发:getSupportFragmentManager()不可用
getSupportFragmentManager()这个函数不可用显然是因为activity继承错误了,因此我们需要将整个类的所继承的类改变即可 public class MainActivity ...
- oracle 死锁 锁
[zhuan]今天看群里在讨论数据库死锁的问题,也一起研究了下,查了些资料在这里总结下. 所谓死锁: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将 ...
- Python—实现ssh客户端(连接远程服务器)
paramiko是一个基于SSH用于连接远程服务器并执行相关操作(SSHClient和SFTPClinet,即一个是远程连接,一个是上传下载服务),使用该模块可以对远程服务器进行命令或文件操作,值得一 ...
- 02vuex-modules
01===> module的理解:将一个大的系统进行拆分 拆分成若干个细的模块 给个模块都有自己的 state mutations 等属性 这样可以在自己的小模块中进行修改 方便维护 modul ...
- Java中Class和单例类的作用与类成员的理解
Java中Class类的作用与深入理解 在程序运行期间,Java运行时系统始终为所有的对象维护一个被称为运行时的类型标识.这个信息跟踪着每个对象所属的类.JVM利用运行时信息选择相应的方法执行.而保存 ...
- 初学JavaScript正则表达式(十三)
字符串方法 search(reg) search()用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串 方法返回第一个匹配结果index,查找不到返回-1 search()不执行全局匹 ...
- CSS百分比padding实现比例固定图片自适应布局
一.CSS百分比padding都是相对宽度计算的 在默认的水平文档流方向下,CSS margin和padding属性的垂直方向的百分比值都是相对于宽度计算的,这个和top, bottom等属性的百分比 ...
- C++ 模板特化、偏特化测试程序
#include <iostream> // 偏特化的模板不会自己添加构造函数 ctor 和 析构函数 dtor #if 1 // P1 template <typename T1, ...
- Vue入门案例(二)
创建一个 .html 文件,然后通过如下方式引入 Vue: <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.js ...
- Python 可执行对象
Python 可执行对象 eval/repr eval eval 可以执行字符串类型的表达式 (或 compile() 创建的代码对象(code object) ) 并返回执行结果 eval(expr ...