今天看到有人说未同步的(非线程安全)ArrayList.SyncRoot返回的是它自己.开始我也这么认为,而且我还认为同步的(线程安全)ArrayList.SyncRoot 也就是包装过的, 返回的是原始的实例. 我用下面的代码试了一下, 发现不管同步与否的ArrayList.SyncRoot都不是它自己, 而且根本不是一个ArrayList. 不过Array.SyncRoot是它自己,而且Array没有提供静态Synchronized方法.
我现在疑问的是ArrayList.SyncRoot 到底是什么? 为什么锁它就行.ArrayList list = new ArrayList();Console.WriteLine("list.IsSynchronized? {0}", list.IsSynchronized);
Console.WriteLine("list.SyncRoot == list? {0}", list.SyncRoot == list);
Console.WriteLine();ArrayList sync = ArrayList.Synchronized(list);
Console.WriteLine("sync.IsSynchronized? {0}", sync.IsSynchronized);
Console.WriteLine("sync.SyncRoot == sync? {0}", sync.SyncRoot == sync);
Console.WriteLine();Console.WriteLine("list == sync? {0}", list == sync);
Console.WriteLine("list.SyncRoot == sync.SyncRoot? {0}", list.SyncRoot == sync.SyncRoot);
Console.WriteLine();Console.WriteLine("list.SyncRoot.GetType() = {0}", list.SyncRoot.GetType());
Console.WriteLine("sync.SyncRoot.GetType() = {0}", sync.SyncRoot.GetType());
Console.WriteLine();Console.WriteLine("list.SyncRoot is ArrayList ? {0}", list.SyncRoot is ArrayList);
Console.WriteLine();int[] array = new int[8];Console.WriteLine("array.IsSynchronized? {0}", array.IsSynchronized);
Console.WriteLine("array.SyncRoot == array? {0}", array.SyncRoot == array);
Console.WriteLine("array.SyncRoot is int[] ? {0}", array.SyncRoot is int[]);
Console.WriteLine();Console.Read();
我现在疑问的是ArrayList.SyncRoot 到底是什么? 为什么锁它就行.ArrayList list = new ArrayList();Console.WriteLine("list.IsSynchronized? {0}", list.IsSynchronized);
Console.WriteLine("list.SyncRoot == list? {0}", list.SyncRoot == list);
Console.WriteLine();ArrayList sync = ArrayList.Synchronized(list);
Console.WriteLine("sync.IsSynchronized? {0}", sync.IsSynchronized);
Console.WriteLine("sync.SyncRoot == sync? {0}", sync.SyncRoot == sync);
Console.WriteLine();Console.WriteLine("list == sync? {0}", list == sync);
Console.WriteLine("list.SyncRoot == sync.SyncRoot? {0}", list.SyncRoot == sync.SyncRoot);
Console.WriteLine();Console.WriteLine("list.SyncRoot.GetType() = {0}", list.SyncRoot.GetType());
Console.WriteLine("sync.SyncRoot.GetType() = {0}", sync.SyncRoot.GetType());
Console.WriteLine();Console.WriteLine("list.SyncRoot is ArrayList ? {0}", list.SyncRoot is ArrayList);
Console.WriteLine();int[] array = new int[8];Console.WriteLine("array.IsSynchronized? {0}", array.IsSynchronized);
Console.WriteLine("array.SyncRoot == array? {0}", array.SyncRoot == array);
Console.WriteLine("array.SyncRoot is int[] ? {0}", array.SyncRoot is int[]);
Console.WriteLine();Console.Read();
list.SyncRoot == list? Falsesync.IsSynchronized? True
sync.SyncRoot == sync? Falselist == sync? False
list.SyncRoot == sync.SyncRoot? Truelist.SyncRoot.GetType() = System.Object
sync.SyncRoot.GetType() = System.Objectlist.SyncRoot is ArrayList ? Falsearray.IsSynchronized? False
array.SyncRoot == array? True
array.SyncRoot is int[] ? True
SyncRoot仅仅是用来“锁”的,锁住了它,你对ArrayList进行操作就不用担心同步问题了。ArrayList al = new ArrayList();
lock(al.SyncRoot)
{
al.Add(......);//这里的操作不会有同步问题。
}
原因只有一个, 那就是锁这个Object不会耽误读取! 有没有人赞同? 谈谈大家的看法!!! 不要只讨论怎么用的, 那样看MSDN就可以了.
{
get
{
if (this._syncRoot == null)
{
Interlocked.CompareExchange(ref this._syncRoot, new object(), null);
}
return this._syncRoot;
}
}
Interlocked.CompareExchange 方法 (Object, Object, Object)
比较两个对象是否相等,如果相等,则替换其中一个对象。
结论,这个SyncRoot本来就是一个object,也不可能用于线程同步……
那MSDN里说锁SyncRoot可以同步线程怎么解释呢?"我猜想SyncRoot的主要作用是ArrayList在做一个IList的包装的时候,返回IList的SyncRoot。"
这里的IList只是个接口, 实际又是什么对象呢?