代码之家  ›  专栏  ›  技术社区  ›  Chris

锁是否会因为意外的线程死亡或类似情况而被卡住

  •  1
  • Chris  · 技术社区  · 14 年前

    我当前修改的代码只是在一段代码周围加了一个简单的锁,这样以后的请求就可以等到第一个请求完成。

    我担心的是,我没有用锁太多,所以我只想看看是否有任何情况下,锁不能得到释放?例如,我不知道如果第一个线程被终止会发生什么(例如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函数的访问权包装在一个锁中,以防止两个线程同时进入而两个线程都发现缓存锁不存在,然后两个线程都创建并返回不同的缓存锁?我有点不习惯考虑线程安全性(假设我正确地使用了这个术语)。

    2 回复  |  直到 14 年前
        1
  •  3
  •   Andrey    14 年前

    自从 lock 只是 Monitor try { } finally { } 不会卡住的。如果应用程序进入 deadlock 州。所以在锁定多个对象时要小心。

    顺便说一句,考虑使用数据库。它可以处理所有这些任务,您不必担心锁和写入文件。还有很多其他的功能。

        2
  •  2
  •   TamusJRoyce    14 年前

    如果要在运行CheckAllVariables时将ProjectID添加到别处,则需要一个单独的锁来访问和使用CacheLockObjects字典。

    您没有调用cacheLockObject中调用其他锁定机制的任何功能。所以看起来硬锁是不可能的。我同意,如果线程在进程中被中止,那么在锁定方面不应该有任何问题。