我当前修改的代码只是在一段代码周围加了一个简单的锁,这样以后的请求就可以等到第一个请求完成。
我担心的是,我没有用锁太多,所以我只想看看是否有任何情况下,锁不能得到释放?例如,我不知道如果第一个线程被终止会发生什么(例如web服务器决定它运行太长而关闭它)。锁会在那个时候自动释放吗?在做这件事的时候我还有什么需要考虑的吗?
这是我认为相关的代码位,以防有什么我正在做的蠢事。。。
我使用的是通过字典访问的私有锁对象,只需在SyncLock语句中包装一些代码(相当于C#lock)。
Public Shared Sub CheckAllVariables(ByVal SourceName As String, ByVal cn As HttpContext)
...
Do While dr.Read
projectID = dr.GetInt32(dr.GetOrdinal("ProjectID"))
Dim cacheLockObject As Object = GetCacheLockObject(projectID)
SyncLock (cacheLockObject)
srcName = String.Format("PROJECT_{0}", projectID)
If cacheCon.CheckNeeded(srcName) Then
RunFullCache(projectID, cn, Nothing)
CheckDerivedVariables(projectID, cn)
CheckHierarchyVariables(projectID, cn)
cn.Session(String.Format("DerivedChecked_{0}", projectID)) = True
projectNames.Add(srcName)
cacheCon.CheckNeeded(srcName) = False
End If
End SyncLock
Loop
...
End Sub
Private Shared CacheLockObjects As New Dictionary(Of Integer, Object)
Public Shared Function GetCacheLockObject(ByVal projectid As Integer) As Object
If Not CacheLockObjects.ContainsKey(projectid) Then
CacheLockObjects(projectid) = New Object()
End If
Return CacheLockObjects(projectid)
End Function
我是否应该将对GetCacheLockObject函数的访问权包装在一个锁中,以防止两个线程同时进入而两个线程都发现缓存锁不存在,然后两个线程都创建并返回不同的缓存锁?我有点不习惯考虑线程安全性(假设我正确地使用了这个术语)。