C#多线程:1.lock关键字以及用法

lock 关键字和 Monitor 类都是在 C# 中用于实现互斥锁(Mutex)的机制,用于确保多个线程之间的同步访问共享资源(主要目的是防止多个线程同时修改共享资源,从而避免数据不一致和竞态条件)其中lock关键字主要用于简化对 Monitor 类的使用。lock 语句在进入块时获得指定对象的互斥锁,并在离开块时释放锁。若无需要更精细控制锁的情况,使用lock关键字即可。

使用案例:


abstract class CounterBase
{
    public abstract void Increment();
    public abstract void Decrement();
}

class CounterWithLock:CounterBase
{
    private readonly object _syncRoot = new object();
    public int Count { get; private set;}

    public override void Increment()
    {
        lock (_syncRoot)
            Count++;
    }

    public override void Decrement()
    {
        lock (_syncRoot)
            Count--;
    }
}

class Counter : CounterBase
{
    public int Count { get; private set;}
    public override void Increment()
    {
            Count++;
    }

    public override void Decrement()
    {
            Count--;
    }

这里主要定义了几个类Counter和CounterWithLock,其中后者对某些资源用lock关键字添加了锁。
接下来在Main函数里进行如下试验:

 static void Main(string[] args)
 {
     //不合理计数
     WriteLine("Incorrect counter");
     var c = new Counter();
     var t1 = new Thread(() => TestCounter(c));
     var t2 = new Thread(() => TestCounter(c));
     var t3 = new Thread(() => TestCounter(c));

     t1.Start();
     t2.Start();
     t3.Start();
     //主线程等待三个线程执行完毕
     t1.Join();
     t2.Join();
     t3.Join();

     WriteLine($"Total count: {c.Count}");
     WriteLine("----------------------------------");

     //合理计数
     WriteLine("Correct counter");
     var d = new CounterWithLock();
     var t4 = new Thread(() => TestCounter(d));
     var t5 = new Thread(() => TestCounter(d));
     var t6 = new Thread(() => TestCounter(d));

     t4.Start();
     t5.Start();
     t6.Start();
     //主线程等待三个线程执行完毕
     t4.Join();
     t5.Join();
     t6.Join();

     WriteLine($"Total count: {d.Count}");
 }

 static void TestCounter(CounterBase c)
 {
     for (int i = 0; i < 10000000; i++)
     {
         c.Increment();
         c.Decrement();
     }
 }

调试结果如下:
调试结果
可以看到Counter类因为不存在线程安全,导致Count值并不稳定。多个线程可能会取出同一个Count值接着进行同样的操作并写回,导致可能递增操作和递减操作的数量不匹配,这种情形被称为竞争条件,竞争条件是多线程环境中非常常见的导致错误的原因。为了确保不会发生以上情形,确保当有线程进行尝试改变Count值的时候,其他进程必须等到直到当前进程完成操作。我们可以使用lock关键字来实现这种行为,如CounterWithLock类所示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值