在构建多线程的应用程序时,我们需要找到一种方式来控制多个线程对共享资源的同步访问。System.Threading命名空间提供了一些以同步为中心的类型。C#编程语言也提供了一个特别的关键字,它能在多线程程序中同步共享数据。
使用C#的lock关键字实现线程同步
同步访问共享资源的首选技术是C#的lock关键字。这个关键字允许定义一段线程同步的代码语句。Lock关键字需要定义一个标记,即一个对象引用,线程在进入锁定范围的时候必须获得这个标记。
如果需要锁定安全成员中的一段代码,比较安全的方式是声明私有的object成员来作为锁标记。一旦一个线程进入锁定范围,在它退出锁定范围且释放锁定之前,其他线程将无法访问锁定标记。因此,如果线程A获得锁定标记,直到它放弃这个锁定标记,其他线程才能进入锁定范围。
下面显示了使用lock关键字来实现线程同步的示例代码:
<span style="font-size:14px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace MultiThread
{
class Program
{
public static object threadLock = new object();
public static int number = 1;
public static void Printer()
{
lock (threadLock)
{
for (int i = 1; i < 11; i++)
{
if (i % 10 != 0)
{
Console.WriteLine("thread {0} output the number:{1}.", Thread.CurrentThread.ManagedThreadId, number++);
}
}
}
}
static void Main(string[] args)
{
//创建线程
Thread SleepThread1 = new Thread(new ThreadStart(Printer));
Thread SleepThread2 = new Thread(new ThreadStart(Printer));
//启动线程
SleepThread1.Start();
SleepThread2.Start();
Console.WriteLine("the sleep thread is over!");
Console.ReadLine();
}
}
}</span>
运行结果如下:
使用System.Threading.Monitor类型进行同步
大多数情况下,使用lock关键字就够用了,但System.Threading.Monitor类型比lock关键字有更好的控制力。
public static void Printer()
{
Monitor.Enter(threadLock);
for (int i = 1; i < 11; i++)
{
if (i % 10 != 0)
{
Console.WriteLine("thread {0} output the number:{1}.", Thread.CurrentThread.ManagedThreadId, number++);
}
}
Monitor.Exit(threadLock);
}
使用Monitor类型还可以使用Monitor.Wait()方法指示活动的线程等待一段时间,在当前线程完成操作时,通知等待线程。