C# Hashtable Synchronized vs SyncRoot

24 篇文章 0 订阅

C# Hashtable Synchronized vs SyncRoot

结合这篇看完,csharp的同步锁问题就差不多了
线程,同步与锁————Lock你到底锁住了谁?
把服务器查询最频繁的表用DataTable缓存在内存....DataTable都是内建索引功能,内存中查询速度极快,当然你得保证同步

 


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为多个线程共享的变量提供原子操作。 原子操作就是单线程操[来源:GameRes.com]作。在一个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对象实例中,不管我们调用多少次,他是唯一的。

 

转自:http://bbs.gameres.com/showthread.asp?threadid=128305

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值