• 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧

我可以锁定类实例变量的副本吗?

c/c++ 来源:Nikos C. 7次浏览

在C#中,类实例是引用类型。这是否意味着可以锁定由new返回的值的副本?在我的情况下,我有一些需要锁定的字段:我可以锁定类实例变量的副本吗?

class Foo { 
    // ... 
    private Dictionary<IAsyncResult, string> fReadRequests; 
    private Dictionary<IAsyncResult, string> fWriteRequests; 
    private Dictionary<IAsyncResult, string> fSyncRequests; 
} 

在一个特定的方法中,我需要对所有这些字段执行相同的操作。因此,为了避免代码重复,我通过将字段复制到数组中来执行循环操作:

var dictArray = new[] { fReadRequests, fWriteRequests, fSyncRequests }; 
foreach (var reqDict in dictArray) { 
    lock (reqDict) { 
     foreach (var i in reqDict) { 
      // Do something with the request. 
     } 
    } 
} 

这是安全吗?即使锁上应用的变量是原件的副本,锁定是否按预期工作?


===========解决方案如下:

是的,你永远不会锁定变量持有参考,你总是锁定实例

你的情况,你复制参考,而不是对象,所以这就是你对工作的同一对象是在这些领域。

锁定这些应该很好。

只知道:

  1. 锁定的对象不以任何方式阻止其他线程访问同一个对象。如果另一个线程未锁定,它将跳入正确的位置,并改变对象而不理会您的锁定。
  2. 请勿锁定您不拥有的对象以及您发布给他人的对象。您需要确保您的代码是锁定该对象的唯一一个,否则如果某些其他代码也对其锁定,那么您的小心同步代码可能会突然停止。
  3. 从不锁定值类型,即使您将它们放在object变量中。每次将值类型复制到object变量中时,您将获得新的副本,该副本将拥有自己的锁定。

为了对抗nbr。 2你通常这样做:

private readonly object fLockReadQuests = new object(); 

然后锁定,而不是。

但是,您的问题的假设仍然存在。


版权声明:本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。
喜欢 (0)