【问题标题】:Considerations when using lock使用锁时的注意事项
【发布时间】:2013-07-30 20:52:56
【问题描述】:

我有一点困惑。我在 c# 中使用一个名为 status 的静态变量,其属性如下

private static bool status;

public static bool Status   
{  
   get { return status; }  
   set { status = value; }  
}

现在我已经分别启动了 2 个线程 第一个线程使用变量状态的属性将值设置为真/假 第二个线程使用变量状态的属性获取值。

在这种情况下,我想会发生什么
如果第一个线程尝试更新变量状态的值,而第二个线程尝试读取变量状态的值

我是否需要对属性内部的这个变量状态使用锁定语句来处理线程同步或不需要? 谁能帮助我澄清这个疑问?

【问题讨论】:

  • 我是这个 c# .net 环境的新手。我看到了那个链接,它看起来非常高级。我无法清楚地理解。您能否得出结论并告诉我是否应该使用 lock 语句
  • 在这种特定情况下,读/写bool 实际上是一个原子操作,所以我认为您不需要锁定它。显然这不适用于所有属性
  • 挖了两年多的坟墓!!

标签: c#


【解决方案1】:

根据您的问题,我了解线程一会产生状态值,而线程二会消耗该值并在此基础上进行一些工作。这里不需要锁,因为从原始类型读取是线程安全的(当您读取数据时,其他线程不会破坏该数据)。仅当您有两个或更多写入器线程要写入数据时才需要锁定。例如,如果您的两个线程都将设置状态值,则需要一个锁定块。

【讨论】:

    【解决方案2】:

    同步访问 inside 属性不会有任何作用,因为锁定旨在防止跨使用该资源的代码块访问共享资源。

    需要同步的是访问该属性的整个块。一般来说,您需要在调用者级别同步访问。

    void Thread1() {
        lock(myObj) {
    
            if(myObj.Status)
                Console.WriteLine("Status is true");
    
            // ...
    
            // myObj.Status is guaranteed to be still true as long as
            // all the code that accesses the property lock myObj.
            if(myObj.Status)
                Console.WriteLine("Status is still true");
    
        }
    }
    

    请注意,您不需要锁定具有该属性的对象。您可以使用另一个对象作为同步机制,只要它在所有相关线程之间共享即可。

    static object mutex = new object();
    
    void Thread1() {
        lock(mutex) {
    
            if(myObj.Status)
                Console.WriteLine("Status is true");
    
            // ...
    
            // myObj.Status is guaranteed to be still true as long as
            // all the code that accesses the property lock myObj.
            if(myObj.Status)
                Console.WriteLine("Status is still true");
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-09
      • 2016-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多