9

在我阅读了这个问题并得到了Marc的回答之后......

我有时会看到人们锁定一个局部变量。

这段代码坏了吗?

public void Do()
{
 object  o  = new Object();
 lock (o)
     {
      ...
     }
}

我相信object o = new Object();应该在方法之外作为一个Field.

由于每个线程都在获取 的新实例o,因此会有多个锁。

我在这里想念什么?在这种特定情况下,它不应该锁定字段吗?

4

5 回答 5

8

我相信object o = new Object();应该在方法之外作为一个Field.

由于每个线程都在获取 的新实例o,因此会有多个锁。

我在这里想念什么?在这种特定情况下,它不应该锁定字段吗?

你的理解是正确的。代码被破坏了。在这个实现中,即使锁处于活动状态,它也不会提供同步,因为它将在不同的对象上。

来自Microsoft 文档

当您同步对共享资源的线程访问时,锁定专用对象实例(例如,私有只读对象 balanceLock = new object();)或另一个不太可能被无关代码部分用作锁定对象的实例. 避免对不同的共享资源使用相同的锁对象实例,因为这可能导致死锁或锁争用。特别是,避免将以下内容用作锁定对象:

这个,因为它可能被调用者用作锁。类型实例,因为这些实例可能通过 typeof 运算符或反射获得。字符串实例,包括字符串文字,因为它们可能被实习。保持锁的时间尽可能短,以减少锁争用。

于 2013-01-07T09:48:09.143 回答
4

是的。它被打破。

您希望将静态只读对象作为私有字段来锁定。正如您所怀疑的那样,您的示例代码每次调用 Do 时都会创建一个新对象,因此锁将没有任何东西可以保留并且根本不起作用。

private static object syncRoot = new object();

lock (syncRoot) { }
于 2013-01-07T09:45:02.080 回答
2

每次调用您的方法时,您都在创建 o 对象。所以,锁不起作用。我的意思是其他线程不会等待锁没有发出信号并控制该锁控制的资源。通常锁对象是类中的私有变量,因此所有方法都查看同一个对象。

于 2013-01-07T09:40:50.270 回答
2

我个人认为没有任何理由使用它,因为只是将 ,实例lock的特殊字段设置为信号状态。因此其他线程可以检查该实例的状态,并基于该状态执行语句中的代码或等待它的释放。olock

每次拥有局部变量都会分配一个新实例,因此对于每个线程都可以。

看不出这有什么意义。

于 2013-01-07T09:40:54.757 回答
1

锁定局部变量,锁定将起作用。锁定全局变量可以生效以同步多个线程。

using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using System.Threading.Tasks;
        using System.Threading;

        namespace testLock
        {
            class Program
            {
                public static void Main()
                {
                    // Start a thread that calls a parameterized static method.
                    for(int i = 0; i< 10;i++)
                    {
                        Thread newThread = new Thread(DoWork);
                        newThread.Start(i);
                    }

                    Console.ReadLine();
                }

                static object gObject= new object();
                public static void DoWork(object data)
                {
                    int len = (int)data % 3;
                    object tmp = new object();
                    Console.WriteLine("to lock...... Data='{0}'  sleepTime:{1}", data, len);
                    lock (tmp)//tmp won't work, change tmp to gObject to see different output, which is good locking case)
                    {
                        Console.WriteLine("in lock...... Data='{0}'  sleepTime:{1}", data, len);

                        Thread.Sleep(  len* 1000);
                        Console.WriteLine("Static thread procedure. Data='{0}'  sleepTime:{1}", data, len);
                    }
                }

            }
        }

    **Lock temp variable,will output:**
    to lock...... Data='1'  sleepTime:1
    in lock...... Data='1'  sleepTime:1
    to lock...... Data='2'  sleepTime:2
    in lock...... Data='2'  sleepTime:2
    to lock...... Data='0'  sleepTime:0
    in lock...... Data='0'  sleepTime:0
    Static thread procedure. Data='0'  sleepTime:0
    to lock...... Data='3'  sleepTime:0
    in lock...... Data='3'  sleepTime:0
    Static thread procedure. Data='3'  sleepTime:0
    to lock...... Data='4'  sleepTime:1
    in lock...... Data='4'  sleepTime:1
    to lock...... Data='5'  sleepTime:2
    in lock...... Data='5'  sleepTime:2
    to lock...... Data='6'  sleepTime:0
    in lock...... Data='6'  sleepTime:0
    Static thread procedure. Data='6'  sleepTime:0
    to lock...... Data='7'  sleepTime:1
    in lock...... Data='7'  sleepTime:1
    to lock...... Data='8'  sleepTime:2
    in lock...... Data='8'  sleepTime:2
    to lock...... Data='9'  sleepTime:0
    in lock...... Data='9'  sleepTime:0
    Static thread procedure. Data='9'  sleepTime:0
    Static thread procedure. Data='1'  sleepTime:1
    Static thread procedure. Data='4'  sleepTime:1
    Static thread procedure. Data='7'  sleepTime:1
    Static thread procedure. Data='2'  sleepTime:2
    Static thread procedure. Data='5'  sleepTime:2
    Static thread procedure. Data='8'  sleepTime:2

    **Then lock gObject, will print:**
    to lock...... Data='0'  sleepTime:0
    in lock...... Data='0'  sleepTime:0
    to lock...... Data='1'  sleepTime:1
    to lock...... Data='2'  sleepTime:2
    Static thread procedure. Data='0'  sleepTime:0
    in lock...... Data='1'  sleepTime:1
    to lock...... Data='3'  sleepTime:0
    to lock...... Data='4'  sleepTime:1
    to lock...... Data='5'  sleepTime:2
    to lock...... Data='6'  sleepTime:0
    to lock...... Data='7'  sleepTime:1
    to lock...... Data='8'  sleepTime:2
    to lock...... Data='9'  sleepTime:0
    Static thread procedure. Data='1'  sleepTime:1
    in lock...... Data='5'  sleepTime:2
    Static thread procedure. Data='5'  sleepTime:2
    in lock...... Data='9'  sleepTime:0
    Static thread procedure. Data='9'  sleepTime:0
    in lock...... Data='2'  sleepTime:2
    Static thread procedure. Data='2'  sleepTime:2
    in lock...... Data='8'  sleepTime:2
    Static thread procedure. Data='8'  sleepTime:2
    in lock...... Data='7'  sleepTime:1
    Static thread procedure. Data='7'  sleepTime:1
    in lock...... Data='4'  sleepTime:1
    Static thread procedure. Data='4'  sleepTime:1
    in lock...... Data='3'  sleepTime:0
    Static thread procedure. Data='3'  sleepTime:0
    in lock...... Data='6'  sleepTime:0
    Static thread procedure. Data='6'  sleepTime:0
于 2017-08-26T09:00:30.733 回答