Vb.net “Synclock syncroot”和“Synclock Me”之间有什么区别?
vb.Net多线程问题: 两者的区别是什么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不同(我假
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