Lock in C#

The lock syntax is:

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

The purpose is that in multi-threading, after using lock, the code block can be executed in the specified order, and the locked code has been accessed by one of the threads, so the other thread can only wait.

If you don't understand the theory, see the breakdown below.

1. Looking at this code, it starts to execute from above, first executes A, and then executes B. This is a single-threaded program, executed in order, and the result can be controlled at this time.

2. We have added multi-threading, which is to let A and B methods be executed at the same time. At this time, the result is uncontrollable. Sometimes method B is executed first, and sometimes method A is executed first.

Execute method B first.

Execute method A first.

As for why A is executed first, then B is executed, or B is executed first, and then A is executed, this is automatically calculated by the operating system based on the CPU. It can be seen that our problem is coming. Can it be done so that it can be executed in multiple threads and control the order of A and B? This will use the lock.

3. Therefore, the effect we want is that in the case of multi-threading, either execute A first or execute B first. A and B cannot be executed nestedly, they must be executed sequentially. Once the program enters the lock, it is locked. The locked code can only be accessed by one thread at this time. Only after the access of this thread is over, other threads can access it.

In order to increase the contrast, we add another C method

Effect

 the code

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

namespace ConsoleApp2
{
    class Program
    {
        static int a = 0;
        static int b = 0;
        private static object o = new object();
        static void Main(string[] args)
        {
            //A();
            //B();
            Thread t1 = new Thread(A);
            Thread t2 = new Thread(B);
            t1.Start();
            t2.Start();
            Thread t3 = new Thread(C);
            t3.Start();
            Console.ReadLine();
        }
        private static void A()
        {
            lock (o)
            {
                a = a + 2;
                Console.WriteLine("我是A方法,a=" + a);
                Thread.Sleep(5000);//暂停5秒
                b = b + 2;
                Console.WriteLine("我是A方法,b=" + b);
            }
        }
        private static void B()
        {
            lock (o)
            {
                b++;
                Console.WriteLine("我是B方法,b=" + b);
                Thread.Sleep(1000); //暂停1秒
                a++;
                Console.WriteLine("我是B方法,a=" + a);
            }
        }
        private static void C()
        {
            Console.WriteLine("我是C方法,随机出现");
        }
    }
}

 expand

In fact, lock is equivalent to Monitor.

lock(o);

{

do 

}

Equivalent to

  Monitor.Enter(o);

{

do

}

 Monitor.Exit(o);

Enter is equivalent to entering this code block, and Exit is to exit this code block. When this block of code runs again, other threads cannot access it. The {} in Monitor can be removed without affecting it.

the code

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

namespace ConsoleApp2
{
    class Program
    {
        static int a = 0;
        static int b = 0;
        private static object o = new object();
        static void Main(string[] args)
        {
            //A();
            //B();
            Thread t1 = new Thread(A);
            Thread t2 = new Thread(B);
            t1.Start();
            t2.Start();
            Thread t3 = new Thread(C);
            t3.Start();
            Console.ReadLine();
        }
        private static void A()
        {
            //lock (o)
            Monitor.Enter(o);

            a = a + 2;
            Console.WriteLine("我是A方法,a=" + a);
            Thread.Sleep(5000);//暂停5秒
            b = b + 2;
            Console.WriteLine("我是A方法,b=" + b);

            Monitor.Exit(o);
        }
        private static void B()
        {
            //lock (o)
            Monitor.Enter(o);

            b++;
            Console.WriteLine("我是B方法,b=" + b);
            Thread.Sleep(1000); //暂停1秒
            a++;
            Console.WriteLine("我是B方法,a=" + a);

            Monitor.Exit(o);
        }
        private static void C()
        {
            Console.WriteLine("我是C方法,随机出现");
        }
    }
}

Guess you like

Origin blog.csdn.net/u012563853/article/details/124767902