5

vb.Net 多线程问题:

和有什么区别

SyncLock syncRoot  
  ''# Do Stuff  
End SyncLock

-和-

SyncLock Me  
  ''# Do Stuff  
End SyncLock
4

3 回答 3

5

块内发生的所有代码都与同一对象的块SyncLock内发生的所有其他代码同步。显然,与(即,我假设,如果您是,则)不同。SyncLockMesyncRootMe.SyncRootMeICollection

在一个对象的块内发生的代码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

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

但是假设你有这个:

' 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属性背后的想法:它为您提供了一个对象,其全部目的是提供一个公共对象,可以同步对集合的修改/枚举。以其他方式涉及集合的代码——但不需要与修改或读取集合内容的代码同步——应该在适当的情况下在不同的对象上同步。

于 2010-05-18T15:13:03.847 回答
3

如果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使用相同对象的 a 保护的代码被有效地序列化。

于 2010-05-18T15:22:53.603 回答
2

您正在锁定不同的对象。

如果您的代码(或内部代码)的其他部分SyncRootMe.

你绝对应该同步SyncRoot——这就是它存在的原因。

于 2010-05-18T15:12:35.953 回答