Vb.net “Synclock syncroot”和“Synclock Me”之间有什么区别?

Vb.net “Synclock syncroot”和“Synclock Me”之间有什么区别?,vb.net,multithreading,synclock,Vb.net,Multithreading,Synclock,vb.Net多线程问题: 两者的区别是什么 SyncLock syncRoot ''# Do Stuff End SyncLock -及- 您正在锁定不同的对象 如果代码的其他部分(或内部代码)在SyncRoot上同步(它们应该同步),那么通过在Me上同步,您正在破坏一些东西(即引入线程错误) 您肯定应该在SyncRoot上同步,这就是它存在的原因。在SyncLock块中发生的所有代码都与同一对象上的SyncLock块中发生的所有其他代码同步。显然,Me与syncRoot不同(我假

vb.Net多线程问题:

两者的区别是什么

SyncLock syncRoot  
  ''# Do Stuff  
End SyncLock
-及-


您正在锁定不同的对象

如果代码的其他部分(或内部代码)在
SyncRoot
上同步(它们应该同步),那么通过在
Me
上同步,您正在破坏一些东西(即引入线程错误)


您肯定应该在
SyncRoot
上同步,这就是它存在的原因。

SyncLock
块中发生的所有代码都与同一对象上的
SyncLock
块中发生的所有其他代码同步。显然,
Me
syncRoot
不同(我假设,
Me.syncRoot
,如果您的
Me
是一个
ICollection

发生在一个对象上的SyncLock块中的代码不会与另一个对象上的SyncLock块中的代码同步

假设您有以下代码:

' happening on thread 1 '
SyncLock myColl.SyncRoot
    myColl.Add(myObject)
End SyncLock

' happening on thread 2 '
SyncLock myColl.SyncRoot
    myColl.Remove(myObject)
End SyncLock
上面的情况很好:
Add
Remove
调用是同步的,这意味着它们不会同时发生(第一个调用的将执行,第二个调用在第一个调用完成之前不会执行)

但假设你有这个:

' happening on thread 1 '
SyncLock myColl.SyncRoot
    myColl.Add(myObject)
End SyncLock

' happening on thread 2 '
SyncLock myColl ' NOTE: SyncLock on a different object '
    myColl.Remove(myObject)
End SyncLock
上述
Add
Remove
调用不以任何方式、形状或形式同步。因此,上述代码中没有线程安全性

现在,为什么存在
SyncRoot
?很简单,因为在必要的最小规模上同步是有意义的;i、 例如,不需要同步实际上不需要同步的代码

考虑这个例子:

' happening on thread 1 '
SyncLock myColl
    myColl.Add(myObject)
End SyncLock

' happening on thread 2 '
SyncLock myColl
    ' Why you would have code like this, I do not know; '
    ' this is just for illustration. '
    myColl.Name = myColl.Name.Replace("Joe", "Bill")
End SyncLock

' happening on thread 3 '
SyncLock myColl
    myColl.Name = myColl.Name.Replace("Bill", "Joe")
End SyncLock
在上面的示例中,您同步的超出了必要的范围。
Add
调用实际上与
myColl
对象的重命名无关;因此,代码不需要同步


这就是
SyncRoot
属性背后的思想:它提供了一个对象,其全部目的是提供一个公共对象,可以与该对象同步对集合的修改/枚举。以其他方式涉及集合的代码(但不需要与修改或读取集合内容的代码同步)应该在不同的对象上同步(如果合适)。

如果object.ReferenceEquals(syncRoot,Me)=True,则没有什么不同。否则,将使用不同的对象获取锁

如果您使用的
syncRoot
相当于
ICollection.syncRoot
,则将使用集合内部用于自身锁定的同一对象获取锁。这允许您同步对枚举数的访问。例如:

SyncLock collection.SyncRoot
  For Each item As Object in collection
  Next
End SyncLock
按照惯例.NET开发人员避免使用
Me
作为锁对象。如果
Me
引用类库的公共API可见的对象,则尤其如此。我们之所以避免这样做,是因为其他代码可能使用相同的对象来获取锁,原因与您试图在代码中实现的语义行为相冲突。这种冲突可能导致瓶颈甚至死锁


应该注意的是,
SyncLock
并不同步对锁对象本身的访问,而是由
SyncLock
构造包装的代码。换句话说,由使用同一对象的
SyncLock
保护的代码被有效地序列化。

我对SyncLock有点困惑。synclock是否阻止对我传递给它的变量进行更改(在本例中是,
syncRoot
),还是它只是锁定了代码?我刚刚注意到,在第二段第一句中,“使用”一词背靠背出现。在内容编辑器文本框中不会以这种方式显示。这么说吧?
SyncLock collection.SyncRoot
  For Each item As Object in collection
  Next
End SyncLock