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
#####
愿你一寸一寸地攻城略地,一点一点地焕然一新
#####