一、前言
通过多线程,程序可以并行执行代码。每一个线程都有它独立的执行路径,所有线程都能够访问共有变量。
以下例子是两个线程并行执行的例子:
class Program
{
static string str = "";
static void Main(string[] args)
{
Thread t1 = new Thread(Add1);
t1.Start();
Thread t2 = new Thread(Add2);
t2.Start();
// 等待一段时间
Thread.Sleep(1000);
// 输出
Console.WriteLine(str);
}
public static void Add1()
{
for (int i = 0; i < 20; i++)
{
Thread.Sleep(10);
str += "A";
}
}
public static void Add2()
{
for (int i = 0; i < 20; i++)
{
Thread.Sleep(10);
str += "B";
}
}
二、改进
因为两个线程并行执行,字符串str时而被Add1操作,时而被Add2操作。
为了避免线程竞争,可以通过加锁(lock)的方式来处理。当两个线程争夺一个锁的时候,一个线程获得锁资源,另一个线程则等待,一直等到锁变为可用为止。这样,就能确保在同一个时刻只有一个线程能够进入临界区。
在不确定的多线程环境中以此方式来处理叫作线程安全。
修改后的程序如下:
class Program
{
static string str = "";
static void Main(string[] args)
{
Thread t1 = new Thread(Add1);
t1.Start();
Thread t2 = new Thread(Add2);
t2.Start();
// 等待一段时间
Thread.Sleep(1000);
// 输出
Console.WriteLine(str);
}
public static void Add1()
{
lock (str)
{
for (int i = 0; i < 20; i++)
{
Thread.Sleep(10);
str += "A";
}
}
}
public static void Add2()
{
lock (str)
{
for (int i = 0; i < 20; i++)
{
Thread.Sleep(10);
str += "B";
}
}
}
}