看网上的文章都说lock的对象要是私有的。但是我看了下ICollection里的syncroot是public的。list,queue都实现了这个syncroot,是不是有矛盾。其实我想实现这样一个功能,有一个实例对象A,我想在不同的线程中锁定这个对象不让其他线程修改。我的想法是在这个对象所在的类里,定义一个锁(比如名字叫lock),在不同的线程中,只要lock(A.lock)就可以实现了。但是lock的对象不能是public的,那我们如果我在类中定义这个lock,就必须声明未public的才能通过A.lock拿到。如果不在类里面定义把这个lock变量跟类封装到一起,难道我每声明一个类的实例,就在下面再声明一个private object, 如果我有10个实例对象在不同的线程中要做互斥,那么我外面要再声明10个 private ojbect么。
List<T> 、Queue<T>这些类的SyncRoot都是私有的,定义如下:[NonSerialized]
private object _syncRoot;
[__DynamicallyInvokable]
object ICollection.SyncRoot
{
[__DynamicallyInvokable] get
{
if (this._syncRoot == null)
Interlocked.CompareExchange<object>(ref this._syncRoot, new object(), (object) null);
return this._syncRoot;
}
}
不知道你说public的结论怎么来的
你的这个实例对象A,它从属于哪个对象,就应该由哪个对象负责它的修改操作(含线程安全保障),简单示例:
public class xxx{
private object a;
public object A{get{return a;}set{lock (a){// 对a进行操作}}}
}
object ICollection.SyncRoot
这个没有修饰符,表示private,并不是public
当然,你要觉得 M$ 的技术大牛,框架师等等水平比不上那些网文的作者。。那也无话可说。。附,lock(A.Lock) 是多余的,在大多数情况只直接 lock(A) 即可。
参考MSDN:
https://docs.microsoft.com/zh-cn/dotnet/api/system.collections.icollection.syncroot?redirectedfrom=MSDN&view=netframework-4.7.2#System_Collections_ICollection_SyncRoot要看你的具体业务场景,我还是建议,在对象内部封装掉线程安全操作,不要在外部到处去lock
这个 A 是在哪里实例化的?由于作用域的关系,并不存在全局对象如果你到处实例化A的话,lock(A.lock)就根本起不到锁定的作用
因此 A.lock 只能是 A 类型的公共的静态属性,自然我就可以在 B.Func() 中 A.lock = null; 来让你的锁定不能得以实现
这就是 lock的对象要是私有的 的原因(定义在本类中也一样)
https://lindexi.gitee.io/post/WPF-%E8%A7%A6%E6%91%B8%E5%88%B0%E4%BA%8B%E4%BB%B6.html