C# 用 lock 线程锁实现对资源的同步访问
C# 用 lock 线程锁实现对资源的同步访问
lock 关键字
虽然 sleep 方法可以控制线程的暂停时间,从而改变多个线程之间的顺序,然而每个线程的执行顺序是随机且不确定的。
线程同步是通过共享线程资源来实现的,允许控制一次执行一个线程并交替执行每个线程。
为了在c#语言中实现线程同步,可以使用lock关键字、monitor类和mutex类。
同步线程最简单的方法之一是使用"lock"语句,它确保被锁定的线程在完成执行之前不能执行任何其他线程。
lock 的语法形式如下所示。
lock(object)
{
//临界区代码
}
lock 后面通常是一个 Object 类型的值,也可以使用 this 关键字来表示。
最好是在 lock 中使用私有的只读的非静态变量或私有的静态成员变量,即使用 Private 或 Private static 修饰的成员。
例如:
private Object obj = new Object();
lock (obj)
{
//临界区代码
}
演示:
创建一个控制台应用程序,该应用程序使用lock关键字来控制奇数线程和偶数线程的打印,要求首先执行偶数线程,然后执行奇数线程。
根据题目要求,代码如下。
using System;
using System.Text;
using System.Threading;
namespace CRApp
{
class Program
{
private static readonly object locker = new object();
static int Main(string[] args)
{
Thread t1 = new Thread(PrintEvenNums);
Thread t2 = new Thread(PrintOddNums);
t1.Start();
t2.Start();
Console.ReadKey();
return (0);
}
public static void PrintEvenNums() // 打印0~10之间的偶数
{
lock (locker)
{
for (int i = 0; i < 10; i++)
{
if (i % 2 == 0)
{
Console.WriteLine(i);
}
Thread.Sleep(10);
}
}
}
public static void PrintOddNums () // 打印0~10之间的奇数
{
lock (locker)
{
for (int i = 0; i < 10; i++)
{
if (i % 2 != 0)
{
Console.WriteLine(i);
}
Thread.Sleep(10);
}
}
}
}
}
运行该程序,结果如下:
0
2
4
6
8
1
3
5
7
9
从上面的运行效果可以看出,奇数线程只有在偶数线程完全打印后才执行,每次运行程序打印的效果都是一样的。
参考:
- 《lock 语句》: https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/statements/lock