线程是否在同步时钟上阻塞
Does thread block on synclock
我在从 Silverlight 调用的 vb.net 模块中获得了以下代码。它基本上是在每个线程的基础上分配唯一的 ID。
Public Module IdManager
Private _threadTrackingIds As New Dictionary(Of Integer, String)
Private _lockObject As New Object
Public Function GetNext() As String
Dim threadId = System.Threading.Thread.CurrentThread.ManagedThreadId
Dim g As String = Guid.NewGuid().ToString()
SyncLock _lockObject
_threadTrackingIds(threadId) = g
End SyncLock
Return g
End Function
Public ReadOnly Property CurrentTrackingID As String
Get
Dim threadId = System.Threading.Thread.CurrentThread.ManagedThreadId
Dim idToReturn As String = String.Empty
SyncLock _lockObject
If (_threadTrackingIds.ContainsKey(threadId)) Then
idToReturn = _threadTrackingIds(threadId)
End If
End SyncLock
Return idToReturn
End Get
End Property
End Module
GetNext()return是一个字符串,但大多数情况下我只是调用它而不检查return值(即只是调用IdManager.GetNext()而不赋值它到一个变量)因为我直到以后才需要这个值(有时是其他方法)所以我只在需要时调用 CurrentTrackingId。
但是,我有多个线程调用它(因此是同步时钟)所以我的问题是:如果 IdManager.GetNext() 没有获得锁,我的调用代码会阻塞调用吗?继续进行直到需要阻塞?也就是说,我想知道是否不将字符串值分配给一个变量(即 z = IdManager.GetNext()),然后也许使用该变量会使调用者忽略它没有获得锁的事实.如果它没有阻塞,那么线程是否会继续执行其余指令而无需设置 CurrentTrackingID?
是的,SyncLock 通过只允许一个线程进入受保护的代码来提供同步。试图在 准确 的同一时间进入的任何其他线程将被阻塞,直到锁被释放。
这种情况实际发生的可能性非常低。但不是零。你持有锁的时间很短,Dictionary 非常高效,只需要一小部分微秒。您必须每秒调用这些方法数十万次才能注意到任何争用。
没什么好担心的。如果绝对必要,您可以回退到 ConcurrentDictionary,它使用更细粒度的锁并且更友好,因为您不必显式使用 SyncLock。
我在从 Silverlight 调用的 vb.net 模块中获得了以下代码。它基本上是在每个线程的基础上分配唯一的 ID。
Public Module IdManager
Private _threadTrackingIds As New Dictionary(Of Integer, String)
Private _lockObject As New Object
Public Function GetNext() As String
Dim threadId = System.Threading.Thread.CurrentThread.ManagedThreadId
Dim g As String = Guid.NewGuid().ToString()
SyncLock _lockObject
_threadTrackingIds(threadId) = g
End SyncLock
Return g
End Function
Public ReadOnly Property CurrentTrackingID As String
Get
Dim threadId = System.Threading.Thread.CurrentThread.ManagedThreadId
Dim idToReturn As String = String.Empty
SyncLock _lockObject
If (_threadTrackingIds.ContainsKey(threadId)) Then
idToReturn = _threadTrackingIds(threadId)
End If
End SyncLock
Return idToReturn
End Get
End Property
End Module
GetNext()return是一个字符串,但大多数情况下我只是调用它而不检查return值(即只是调用IdManager.GetNext()而不赋值它到一个变量)因为我直到以后才需要这个值(有时是其他方法)所以我只在需要时调用 CurrentTrackingId。
但是,我有多个线程调用它(因此是同步时钟)所以我的问题是:如果 IdManager.GetNext() 没有获得锁,我的调用代码会阻塞调用吗?继续进行直到需要阻塞?也就是说,我想知道是否不将字符串值分配给一个变量(即 z = IdManager.GetNext()),然后也许使用该变量会使调用者忽略它没有获得锁的事实.如果它没有阻塞,那么线程是否会继续执行其余指令而无需设置 CurrentTrackingID?
是的,SyncLock 通过只允许一个线程进入受保护的代码来提供同步。试图在 准确 的同一时间进入的任何其他线程将被阻塞,直到锁被释放。
这种情况实际发生的可能性非常低。但不是零。你持有锁的时间很短,Dictionary 非常高效,只需要一小部分微秒。您必须每秒调用这些方法数十万次才能注意到任何争用。
没什么好担心的。如果绝对必要,您可以回退到 ConcurrentDictionary,它使用更细粒度的锁并且更友好,因为您不必显式使用 SyncLock。