線程安全的ArrayList和HashTable
在.net 2.0中,ArrayList和HashTable都有一個封裝了同步功能的新實現.
它們可以通過ArrayList.Synchronized方法或者HashTable.Synchronized方法來獲得.
下面是方法的具體實現:
代碼
[HostProtection(SecurityAction.LinkDemand, Synchronization=true)]
public static ArrayList Synchronized(ArrayList list)
{
if (list == null)
{
throw new ArgumentNullException("list");
}
return new SyncArrayList(list);
}
[HostProtection(SecurityAction.LinkDemand, Synchronization=true)]
public static IList Synchronized(IList list)
{
if (list == null)
{
throw new ArgumentNullException("list");
}
return new SyncIList(list);
}
[HostProtection(SecurityAction.LinkDemand, Synchronization=true)]
public static Hashtable Synchronized(Hashtable table)
{
if (table == null)
{
throw new ArgumentNullException("table");
}
return new SyncHashtable(table);
}
里面的SyncHashtable之流便是同步的HashTable了,
再看看它的實現
代碼
[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;
}
}
}
}
這下明白了吧,就是給ArrayList和HashTable的訪問方法加了個lock,
不過,這可比我們自己手寫還是要靠譜的多..(注意:在進行軼代時,并不是線程安全的。如果要求絕對的線程安全,可以自行lock對象的SyncRoot)
不過有些場景可是不能lock太過的,比如讀寫比很高的場景(很少寫,而讀很多)
不過不用擔心,并發環境下的緩存容器性能優化(上):不可變的哈希表
老趙的這篇文章已經有了很好的解決辦法了.



浙公網安備 33010602011771號