vb.Net多线程问题:

之间有什么区别

SyncLock syncRoot
  ''# Do Stuff
End SyncLock

-和-
SyncLock Me
  ''# Do Stuff
End SyncLock

最佳答案

SyncLock块中发生的所有代码都与在同一对象上的SyncLock块中发生的所有其他代码同步。显然,MesyncRoot不同(如果您的Me.SyncRootMe,我假设是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

上面的方法很好:AddRemove调用是同步的,这意味着它们不会同时发生(首先调用的将执行,而第二个调用将在第一个完成之前不执行)。

但是,假设您有以下方法:
' 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

上面的AddRemove调用是而不是以任何方式,形状或形式同步的。因此,以上代码中没有线程安全性。

现在,为什么SyncRoot存在?很简单,因为在必要的最小规模上进行同步是有意义的。即,不需要同步实际上不需要同步的代码。

考虑以下示例:
' 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属性背后的思想:它为您提供了一个对象,其目的是提供一个公共(public)对象,通过该对象可以同步对集合的修改/枚举。涉及集合的其他某种代码(但不必与修改或读取集合内容的代码同步)应在适当的情况下在不同的对象上同步。

关于vb.net - `Synclock syncroot`和 `SyncLock Me`有什么区别?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2858540/

10-10 13:45