在MSDN文档说,
public class SomeObject
{
public void SomeOperation()
{
lock(this)
{
//Access instance variables
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果可以公开访问实例,那就是"一个问题".我想知道为什么?是因为锁定的持有时间超过了必要的时间吗?还是有一些更阴险的原因?
我正在阅读描述SyncRoot模式的ac#book.表明
void doThis()
{
lock(this){ ... }
}
void doThat()
{
lock(this){ ... }
}
Run Code Online (Sandbox Code Playgroud)
并与SyncRoot模式进行比较:
object syncRoot = new object();
void doThis()
{
lock(syncRoot ){ ... }
}
void doThat()
{
lock(syncRoot){ ... }
}
Run Code Online (Sandbox Code Playgroud)
但是,我真的不明白这里的区别; 似乎在这两种情况下,两种方法一次只能由一个线程访问.
本书描述了...因为实例的对象也可以用于从外部进行同步访问而你无法控制这个类本身的类型,你可以使用SyncRoot模式呃?"实例的对象"?
谁能告诉我上述两种方法之间的区别?
每个人都使用很多List.我需要迭代这个列表,所以我使用已知的SyncRoot模式.
最近我在这篇文章中注意到应该避免使用SyncRoot以支持"嵌入式"线程安全(每个方法将锁定私有对象而不使用SyncRoot属性暴露它).我能理解,部分我同意这一点.
问题是List <T>类没有实现SyncRoot属性,即使实现了ICollection接口,它暴露了SyncRoot属性.我说这会使代码失效
List<int> list = new List<int>()
list.SyncRoot;
Run Code Online (Sandbox Code Playgroud)
给我以下编译器错误:
错误CS0117:'System.Collections.Generic.List'不包含'SyncRoot'的定义
...如果这是真的,我怎么能在迭代它时同步List <T>类型的公共属性?
我一直在阅读有关syncroot元素但我无法在List类型中找到它.那么应该如何使用System.Collections.Generic.List <>类型完成多线程同步?
我试图理解ICollection中syncroot的意义.为什么不直接锁定集合?
lock(myCollection)
{
//do stuff to myCollection
}
Run Code Online (Sandbox Code Playgroud)
VS
lock(myCollection.SyncRoot)
{
//do stuff to myCollection
}
Run Code Online (Sandbox Code Playgroud) 如果有任何不利的一面收集锁定在如我想知道List<T>,HashSet<T>或Dictionary<TKey, TValue>而不是简单的object.
注意:在以下示例中,这是锁定发生的唯一位置,它不会从多个位置锁定,但可以从多个线程调用静态方法.此外,_dict永远不会在GetSomething方法之外访问.
我当前的代码如下所示:
private static readonly Dictionary<string, string> _dict = new Dictionary<string, string>();
public static string GetSomething(string key)
{
string result;
if (!_dict.TryGetValue(key, out result))
{
lock (_dict)
{
if (!_dict.TryGetValue(key, out result))
{
_dict[key] = result = CalculateSomethingExpensive(key);
}
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
另一位开发人员告诉我,锁定集合会引起问题,但我持怀疑态度.如果我这样做,我的代码会更有效吗?
private static readonly Dictionary<string, string> _dict = new Dictionary<string, string>();
private static readonly object _syncRoot = new object();
public static string …Run Code Online (Sandbox Code Playgroud)