VB.NET如果我想锁定多个东西,我需要多个SyncLocks吗?

Bri*_*ahy 1 vb.net multithreading locking list

VB.NET 2010,.NET 4

大家好,

我的问题是,想象我有两个List(Of T)对象和多线程环境中的一个子程序,它修改了这两个对象.我不太了解锁,所以我不确定我是否可以这样做:

SyncLock CType(List1, IList).SyncRoot

  List1.Clear()
  List2.Clear()

End SyncLock
Run Code Online (Sandbox Code Playgroud)

或者我必须:

SyncLock CType(List1, IList).SyncRoot
  SyncLock CType(List2, IList).SyncRoot

    List1.Clear()
    List2.Clear()

  End SyncLock
End SyncLock
Run Code Online (Sandbox Code Playgroud)

?任何见解?我是否走在正确的轨道上?任何意见将不胜感激.

布莱恩,非常感谢

Mat*_*ker 7

首先,锁定非私有对象是不好的做法,因为其他东西可能锁定它,然后事情从那里走下坡路,而不是锁定私有成员对象,类似于

Class Class1
    Private lockObject as New Object

    Public Sub Clear()
        SyncLock lockObject
           ...
        End Synclock
    End Sub
End Class
Run Code Online (Sandbox Code Playgroud)

现在,对于实际问题:除非您执行的每个操作都修改了两个列表(可疑),否则每个列表应该有一个锁.虽然可以使用一个锁定对象来表示"我正在使用列表执行某些操作",但阻止另一个不与您运行在同一列表中的线程中的方法没有多大意义,并且只会减慢一切都好.

因此,简而言之:每组锁使用一个锁对象(用于在list1上操作的锁,用于列表2的锁等).对于在两个列表上运行的部分,代码稍微多一些,但代码将更高效.

另外,作为一般说明:保持锁定的时间尽可能短.你花在锁上的时间越少,另一个线程出现的可能性就会越小,并且在你完成之前就会被阻塞.

SyncLock上MSDN页面也可能值得阅读,它包含此信息和一些示例.@BasicLife是正确的,总是确保在任何地方以相同的顺序取锁.

整个框架中的一般规则,除非您访问类上的静态成员,除非另有说明,否则它不是线程安全的.所以当在列表上操作时,你会想要在列表上添加,删除,清除或枚举时锁定,我确定还有其他的,但这些是最常见的.