为什么"锁定"关键字一个对象参数

0 c# multithreading synchronization locking

我不会说英语而且我使用翻译.

我想知道我什么时候学习线程同步.

class MainApp
{
    static public int count = 0;
    static private object tLock = new object();

    static void plus()
    {
        for (int i = 0; i < 100; i++)
        {
            lock (tLock)
            {
                count++;
                Console.WriteLine("plus " + count);
                Thread.Sleep(1);
            }
        }
    }

    static void minus()
    {
        for (int i = 0; i < 100; i++)
        {
            lock (tLock)
            {
                count--;
                Console.WriteLine("minus " + count);
                Thread.Sleep(1);
            }
        }
    }

    static void Main()
    {
        Thread t1 = new Thread(new ThreadStart(plus));
        Thread t2 = new Thread(new ThreadStart(minus));

        t1.Start();
        t2.Start();
    }
}
Run Code Online (Sandbox Code Playgroud)

简单的线程学习.

static private object tLock = new object();

lock(tLock)<<参数值,为什么对象参数?

Kev*_*sse 6

为什么要有对象参数lock

好吧,因为它很方便.

首先,在您的代码示例中显而易见的是,在调用之间需要一些共享状态lock,以声明两个不同的代码段是互斥的.如果语法只是lock { }没有参数,像这样:

public void DoSomestuff()
{
    lock
    {
        // Section A
    }
}

public void DoOtherStuff()
{
    lock
    {
        // Section B
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,所有锁都将是互斥的,或者只会影响它们各自的代码部分(因此两个线程可以同时执行A和B部分,但一次只能执行一个线程A).这将大大降低关键字的实用性.

现在我们确定我们需要一个共享状态,这个状态应该是什么?我们本来可以使用一个字符串:

lock ("My Section")
{
    // Section A
}
Run Code Online (Sandbox Code Playgroud)

它会起作用,但有一些缺点:

  1. 您将自己暴露给不同库中不同部分的名称之间的潜在冲突
  2. 这意味着运行时必须保留一种表以将字符串与锁相关联.没什么太难的,但这是一些开销

相反,.NET作者去使用对象参数.这解决了问题1 /,因为您知道除非您愿意提供,否则另一个库将不会引用您的对象.但这也解决了问题2 /,因为这允许运行时将锁存储在实际的对象头中.这是一个非常巧妙的优化.