2

我总是在人们使用的 SyncLock 示例中看到

    Private Lock1 As New Object ' declaration
    SyncLock Lock1 ' usage

但为什么?在我的具体情况下,我锁定了一个队列以避免多线程入队和出队我的数据出现问题。

我可以像这样锁定 Queue 对象本身吗?

    Private cmdQueue As New Queue(Of QueueItem) ' declaration
    SyncLock cmdQueue ' usage

任何帮助表示赞赏。谢谢。

编辑:

感谢所有答案,但 tcarvin 答案是我正在寻找的。该队列对于我的单例 Comms 对象是私有的,该对象对要发送的新消息进行排队(由 Send 方法公开),该队列在该对象内的工作线程中一次一条消息被使用,并且我在锁中拥有的唯一代码是一次调用 Enqueue 和 Dequeue。

4

4 回答 4

3

肯定来自其他海报的圣人建议。但答案是肯定的,你可以使用 Queue 对象来锁定。您可以使用任何对象。在您的代码片段中,您将队列实例声明为私有,因此您可能会避免其他人锁定您的队列对象的常见问题(假设您没有将对象传递到您的类之外)。最佳实践建议使用专用对象,这样,在未来,有人不会更改您的代码,然后公开用于锁定的队列对象。

于 2012-06-08T15:48:38.703 回答
2

这是关于锁的常见误解。锁的作用是阻止代码,而不是赋予对象线程安全性。该对象仅用于跟踪锁的状态。而且由于您想阻止特定的代码,您需要一个特定的对象来存储锁定状态。公共队列不够具体,它必然会被其他地方的其他代码使用。如果它还滥用队列对象来阻塞自己的代码,那么出现严重死锁问题的可能性就很高。

锁定对象以实现线程安全的概念实际上是存在的,它是我的机器似乎从未接触过的深入研究的主题。它被称为STM,“软件事务记忆”。维基百科文章在这里

于 2012-06-08T12:13:20.847 回答
1

问题是其他人可以锁定您的对象,这将超出您的控制范围。请参阅 Microsoft 在此lock 语句上的最佳实践

于 2012-06-08T10:41:38.463 回答
-1

我认为您所做的是不好的做法,因为锁定的对象必须保持不变。由于您锁定 aQueue(Of QueueItem)然后您从同一个 Queue 中出列,因此对象会更改,并且如此处所述:https ://msdn.microsoft.com/en-us/library/3a86s51t.aspx (第二条规则),

该机制要求锁定对象保持不变。

所以你应该这样做Public StatusObject As New Object并锁定它

于 2016-08-01T20:51:38.557 回答