C#中的lock

C#中的lock

lock语法为:

private object o = new object();//创建一个对象
public void Work()
{
  lock(o)//锁住这个对象
  {
    //做一些必须按照顺序做的事情
  }
}

相当于:

private object o = new object();//创建一个对象
public void Work()
{
  Monitor.Enter(o);
  //做一些必须按照顺序做的事情
  Monitor.Exit(0);
}

目的是,在多线程中,使用lock后,能使该代码块按照指定的顺序执行,被lock这块代码已经被其中一个线程访问了,那么另外一个线程只能等待。

例子:

static int a = 0;
        static int b = 0;
        static void A()
        {
            a += 2;
            Console.WriteLine($"In A,a={a}");
            Thread.Sleep(5000);
            b += 2;
            Console.WriteLine($"In A,b={b}");
        }

        static void B()
        {
            b++;
            Console.WriteLine($"In B,b={b}");
            Thread.Sleep(1000);
            a++;
            Console.WriteLine($"In B,a={a}");
        }

        static void Main()
        {
            A();
            B();
            Console.ReadLine();
        }

按照单线程,先执行A,然后B,没有问题。

output:

In A,a=2
In A,b=2
In B,b=3
In B,a=3

改为:

static void Main()
        {
            Task t1 = new Task(A);
            Task t2 = new Task(B);
            t1.Start();
            t2.Start();
            Console.ReadLine();
        }

output:

In A,a=2
In B,b=1
In B,a=3
In A,b=3

而我们期望,不论是先执行A还是B,在同一个时间,一个线程执行A或者B,即使用线程锁lock的时候,不会出现两个线程抢占执行函数的情况;

static object o=new object();//锁对象
        static int a = 0;
        static int b = 0;
        static void A()
        {
            lock (o)//锁定同一对象,仅允许同一时间,一个线程进行如下操作
            {
                a += 2;
                Console.WriteLine($"In A,a={a}");
                Thread.Sleep(5000);
                b += 2;
                Console.WriteLine($"In A,b={b}");
            }

        }

        static void B()
        {
            lock (o)//锁定同一对象,仅允许同一时间,一个线程进行如下操作
            {
                b++;
                Console.WriteLine($"In B,b={b}");
                Thread.Sleep(1000);
                a++;
                Console.WriteLine($"In B,a={a}");
            }
            
        }

        static void Main()
        {
            Task t1 = new Task(A);
            Task t2 = new Task(B);
            t1.Start();
            t2.Start();
            Console.ReadLine();
        }

output:

In B,b=1
In B,a=1
In A,a=3
In A,b=3

output:

In A,a=2
In A,b=2
In B,b=3
In B,a=3
posted @ 2023-01-03 12:56  JohnYang819  阅读(2597)  评论(0编辑  收藏  举报