vb.Net multithreading question:
What is the difference between
SyncLock syncRoot
''# Do Stuff
End SyncLock
-and-
SyncLock Me
''# Do Stuff
End SyncLock
All code that happens within a SyncLock
block is synchronized with all other code happening within a SyncLock
block on the same object. Obviously, Me
is not the same as syncRoot
(which is, I'm assuming, Me.SyncRoot
, if your Me
is an ICollection
).
Code happening within a SyncLock
block on one object is not going to be synchronized with code within a SyncLock
block on a different object.
Say you have this code:
' happening on thread 1 '
SyncLock myColl.SyncRoot
myColl.Add(myObject)
End SyncLock
' happening on thread 2 '
SyncLock myColl.SyncRoot
myColl.Remove(myObject)
End SyncLock
The above is fine: the Add
and Remove
calls are synchronized, meaning they will not occur simultaneously (whichever gets called first will execute, and the second will not execute until the first is finished).
But suppose you had this instead:
' 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
The above Add
and Remove
calls are not synchronized in any way, shape, or form. Thus there is no thread safety in the above code.
Now, why does SyncRoot
exist? Quite simply, because it makes sense to synchronize on the smallest scale necessary; i.e., there is no need to synchronize code that doesn't actually need to be synchronized.
Consider this example:
' 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
In the above, you are synchronizing more than necessary. The Add
call really has nothing to do with the renaming of the myColl
object; thus the code does not need to be synchronized.
This is the idea behind the SyncRoot
property: it gives you an object whose entire purpose is to provide a common object with which modifications to/enumerations of the collection can be synchronized. Code that involves the collection in some other way -- but which does not need to be synchronized with code that modifies or reads the contents of the collection -- should be synchronized, where appropriate, on a different object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With