使用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