关于C#多线程中的线程锁,我会分以下几个方面进行全面的讲解:
- 什么是线程锁?
- C#中线程锁的使用方法
- 实例1:使用线程锁的经典示例——银行取钱
- 实例2:使用线程锁处理多线程并发访问共享资源的问题——购票系统
1. 什么是线程锁?
线程锁是一种多线程管理技术,用来控制多个线程之间的访问顺序,避免出现对共享资源的并发访问冲突,从而保证程序在多线程环境下的正确性和稳定性。
2. C#中线程锁的使用方法
C#中通过lock关键字来实现线程锁,具体使用方法如下:
lock (锁定对象)
{
//访问共享资源的代码
}
其中,锁定对象可以是任何对象,只要在多个线程间都能访问到即可。
需要注意的是,在使用lock关键字时,应该只锁定必要的代码块,并在代码块内的操作完成后释放锁定,避免出现死锁现象。
3. 实例1:使用线程锁的经典示例——银行取钱
下面我们通过一个经典的示例来介绍如何在C#中使用线程锁:银行取钱。
假设我们有一个银行账户,账户余额10000,现在需要两个线程同时进行取钱操作。由于取钱操作是对共享资源——账户余额的访问,因此需要对其进行加锁处理,避免出现并发访问冲突。
示例代码如下:
class BankAccount
{
private object lockObj = new object();//定义锁对象
private int balance;
public int Balance
{
get { return balance; }
}
public BankAccount(int balance)
{
this.balance = balance;
}
public void Withdraw(int amount)
{
lock (lockObj)//锁定代码块
{
if (balance >= amount)
{
Console.WriteLine($"正在进行取钱操作,取出{amount}元...");
balance -= amount;//取钱
Console.WriteLine($"取款成功,余额为{balance}元。");
}
else
{
Console.WriteLine($"余额不足,无法完成取款操作。");
}
}
}
}
class Program
{
static void Main(string[] args)
{
BankAccount account = new BankAccount(10000);
Thread t1 = new Thread(() => account.Withdraw(5000));
Thread t2 = new Thread(() => account.Withdraw(6000));
t1.Start();
t2.Start();
Console.ReadKey();
}
}
运行结果:
正在进行取钱操作,取出5000元...
取款成功,余额为5000元。
正在进行取钱操作,取出6000元...
余额不足,无法完成取款操作。
从运行结果可以看出,通过对取款操作进行加锁,避免了多个线程同时对银行账户进行访问的情况发生,从而保证了账户余额正确性。
4. 实例2:使用线程锁处理多线程并发访问共享资源的问题——购票系统
在一个购票系统中,存在多个线程同时访问共享资源(即多个终端同时购买同一个演出的票),这就容易出现并发访问冲突,从而导致购票结果不正确。
要解决这个问题,我们可以通过使用线程锁来控制并发访问,从而保证购票的正确性。
示例代码如下:
class TicketSystem
{
private object lockObj = new object();//定义锁对象
private int totalTicketNum;//剩余票数
public TicketSystem(int totalTicketNum)
{
this.totalTicketNum = totalTicketNum;
}
public void SellTicket(int buyTicketNum, string buyerName)
{
lock (lockObj)//锁定代码块
{
if (totalTicketNum >= buyTicketNum)
{
Console.WriteLine($"正在为买家{buyerName}办理购票业务,共购买{buyTicketNum}张票...");
totalTicketNum -= buyTicketNum;//购买票数减少
Console.WriteLine($"购买成功!买家{buyerName}一共购买了{buyTicketNum}张票。当前余票{totalTicketNum}张。");
}
else
{
Console.WriteLine($"不好意思,买家{buyerName}的请求购票数{buyTicketNum}张已超出余票范围,购票失败。当前余票{totalTicketNum}张。");
}
}
}
}
class Program
{
static void Main(string[] args)
{
TicketSystem ts = new TicketSystem(100);
Thread t1 = new Thread(() =>
{
for (int i = 0; i < 5; i++)
{
ts.SellTicket(2, "用户A");
}
});
Thread t2 = new Thread(() =>
{
for (int i = 0; i < 5; i++)
{
ts.SellTicket(3, "用户B");
}
});
t1.Start();
t2.Start();
Console.ReadKey();
}
}
运行结果:
正在为买家A办理购票业务,共购买2张票...
正在为买家B办理购票业务,共购买3张票...
购买成功!买家A一共购买了2张票。当前余票96张。
不好意思,买家B的请求购票数3张已超出余票范围,购票失败。当前余票96张。
正在为买家A办理购票业务,共购买2张票...
购买成功!买家A一共购买了2张票。当前余票94张。
正在为买家B办理购票业务,共购买3张票...
购买成功!买家B一共购买了3张票。当前余票91张。
正在为买家A办理购票业务,共购买2张票...
正在为买家B办理购票业务,共购买3张票...
购买成功!买家A一共购买了2张票。当前余票86张。
不好意思,买家B的请求购票数3张已超出余票范围,购票失败。当前余票86张。
正在为买家A办理购票业务,共购买2张票...
购买成功!买家A一共购买了2张票。当前余票84张。
正在为买家B办理购票业务,共购买3张票...
购买成功!买家B一共购买了3张票。当前余票81张。
正在为买家A办理购票业务,共购买2张票...
正在为买家B办理购票业务,共购买3张票...
购买成功!买家A一共购买了2张票。当前余票76张。
不好意思,买家B的请求购票数3张已超出余票范围,购票失败。当前余票76张。
从运行结果可以看出,通过使用线程锁,成功避免了多个用户同时购买同一张票的情况发生,从而保证了购票系统的正确性和稳定性。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#多线程之线程锁 - Python技术站