System.Collections.XX.Synchronized()

   我们认真一点就会发现System.Collections名称空间中几乎所有的容器类帮助文档都有类似下面的一段话:

   Hashtable

   Hashtable 是线程安全的,可由多个读取器线程或一个写入线程使用。多线程使用时,如果任何一个线程执行写入(更新)操作,它都不是线程安全的。若要支持多个编写器,如果没有任何线程在读取 Hashtable 对象,则对 Hashtable 的所有操作都必须通过Synchronized方法返回的包装完成。

  ArrayList

  只要集合未修改,ArrayList 就可以同时支持多个阅读器。若要保证 ArrayList 的线程安全,则必须通过由 Synchronized方法返回的包装来执行所有操作。

  用 Reflector 查看Hashtable.Synchronized方法。

[HostProtection(SecurityAction.LinkDemand, Synchronization=true)]
public static Hashtable Synchronized(Hashtable table)
{
    
if (table == null)
    {
        
throw new ArgumentNullException("table");
    }
    
return new Hashtable.SyncHashtable(table);
}

我们发现该方法创建了一个Hashtable的子类SyncHashtable实例。

View Code
using System;
using System.Collections;
using System.Reflection;
using System.Runtime.Serialization;

[Serializable]
private class SyncHashtable : Hashtable
{
    
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()
    {
        
object obj1;
        
lock (this._table.SyncRoot)
        {
            obj1 
= Hashtable.Synchronized((Hashtable)this._table.Clone());
        }
        
return obj1;
    }

    
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)
    {
        
bool flag1;
        
lock (this._table.SyncRoot)
        {
            flag1 
= this._table.ContainsValue(key);
        }
        
return flag1;
    }

    
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();
    }

    
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
        {
            ICollection collection1;
            
lock (this._table.SyncRoot)
            {
                collection1 
= this._table.Keys;
            }
            
return collection1;
        }
    }

    
public override object SyncRoot
    {
        
get
        {
            
return this._table.SyncRoot;
        }
    }

    
public override ICollection Values
    {
        
get
        {
            ICollection collection1;
            
lock (this._table.SyncRoot)
            {
                collection1 
= this._table.Values;
            }
            
return collection1;
        }
    }

    
protected Hashtable _table;
}

原来.net Framework已经替我们写好了lock方法的包装。可以解决多线程的问题。

posted @ 2011-05-19 15:57  mracle  阅读(296)  评论(0编辑  收藏  举报