C# 线程锁Lock 死锁
使用lock场景
- 多线程环境中,不使用lock锁,会形成竞争条件,导致错误。
- 使用lock 锁 可以保证当有线程操作某个共享资源时,其他线程必须等待直到当前线程完成操作。
即是多线程环境,如果一个线程锁定了共享资源,需要访问该资源的其他线程则会处于阻塞状态,并等待直到该共享资源接触锁定。
using System;
using System.Threading;
namespace testthread_keyword_lock
{
class Program
{
static void Main(string[] args)
{
//不使用lock锁
Console.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();
Console.WriteLine("Total count:{0}", c.Count);
Console.WriteLine("------------------------");
Console.WriteLine("correct counter");
var c1 = new CountWithLock();
t1 = new Thread(()=>testCounter(c1));
t2 = new Thread(() => testCounter(c1));
t3 = new Thread(() => testCounter(c1));
t1.Start();
t2.Start();
t3.Start();
t1.Join();
t2.Join();
t3.Join();
Console.WriteLine("Total count:{0}", c1.Count);
}
static void testCounter(CounterBase c)
{
for (int i = 0; i < 100; i++)
{
c.Increment();
c.Decrement();
}
}
}
//定义抽象类
abstract class CounterBase
{
public abstract void Increment();
public abstract void Decrement();
}
//继承 抽象类
class Counter : CounterBase
{
public int Count { get; private set; }
//实现抽象方法
public override void Increment()
{
Count++;
}
public override void Decrement()
{
Count--;
}
}
//lock锁
class CountWithLock : 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--;
}
}
}
}
结果
死锁
- 使用lock时注意共享资源使用,不然可能造成deadlock
- 使用monitor类 其拥有TryEnter方法,该方法接收一个超时参数。如果我们能够在获取被lock保护的资源之前,超时参数过期。则该方法会返回false