Lock锁机制在线程中的应用
(一)锁的概念
代码
public static class ThreadExt
{
public static void WriteLine(this Thread t, string remark, params Thread[] threads)
{
DateTime dt = DateTime.Now;
System.Diagnostics.StackFrame stf = new System.Diagnostics.StackTrace(true).GetFrame(1);
StringBuilder sb = new StringBuilder();
foreach (Thread item in threads)
{
sb.AppendFormat("[线程名:{0,-5} ID:{1} 状态:{2,-12}]\t", item.Name, item.ManagedThreadId, item.ThreadState);
}
Console.WriteLine("{0:HH:mm:ss.fff} L:{6,-4}{1,-12}\t当前线程名:{2,-5} ID:{3} 状态:{4,-13} {5}",
dt, remark, t.Name, t.ManagedThreadId, t.ThreadState, sb.ToString(), stf.GetFileLineNumber());
}
}
class MonitorSample
{
private static readonly object _syncObj = new Object();
static void P(object mainObj)
{
Thread main = mainObj as Thread;
Thread.CurrentThread.WriteLine("P:lock()前 ", main);
lock (_syncObj)
{
Thread.CurrentThread.WriteLine("P:进入Lock ", main);
Thread.Sleep(5000);
Thread.CurrentThread.WriteLine("P:退出Lock ", main);
}
Thread.CurrentThread.WriteLine("P:结束 ", main);
}
static void Main(string[] args)
{
Thread t = new Thread(new ParameterizedThreadStart(P));
t.Name = "P";
Thread.CurrentThread.Name = "Main";
t.Start(Thread.CurrentThread);
Thread.CurrentThread.WriteLine("Main:lock()前 ", t);
lock (_syncObj)
{
Thread.CurrentThread.WriteLine("Main:进入Lock ", t);
Thread.Sleep(5000);
Thread.CurrentThread.WriteLine("Main:退出Lock ", t);
}
Thread.CurrentThread.WriteLine("Main:结束 ", t);
}
}
代码分析如下:
(二)死锁
代码
public static class ThreadExt
{
public static void WriteLine(this Thread t, string remark, params Thread[] threads)
{
DateTime dt = DateTime.Now;
System.Diagnostics.StackFrame stf = new System.Diagnostics.StackTrace(true).GetFrame(1);
StringBuilder sb = new StringBuilder();
foreach (Thread item in threads)
{
sb.AppendFormat("[线程名:{0,-5} ID:{1} 状态:{2,-12}]\t", item.Name, item.ManagedThreadId, item.ThreadState);
}
Console.WriteLine("{0:HH:mm:ss.fff} L:{6,-4}{1,-12}\t当前线程名:{2,-5} ID:{3} 状态:{4,-13} {5}",
dt, remark, t.Name, t.ManagedThreadId, t.ThreadState, sb.ToString(), stf.GetFileLineNumber());
}
}
class MonitorSample
{
private static readonly object _syncObj1 = new Object();
private static readonly object _syncObj2 = new Object();
static void P(object mainObj)
{
Thread main = mainObj as Thread;
Thread.CurrentThread.WriteLine("P:lock()前 ", main);
lock (_syncObj2)
{
Thread.CurrentThread.WriteLine("P:进入Lock2 ", main);
Thread.Sleep(1000);
Thread.CurrentThread.WriteLine("P:进入Sleep ", main);
lock (_syncObj1)
{
Thread.CurrentThread.WriteLine("P:进入Lock1 ", main);
Thread.Sleep(5000);
Thread.CurrentThread.WriteLine("P:退出Lock1 ", main);
}
}
Thread.CurrentThread.WriteLine("P:结束 ", main);
}
static void Main(string[] args)
{
Thread t = new Thread(new ParameterizedThreadStart(P));
t.Name = "P";
Thread.CurrentThread.Name = "Main";
t.Start(Thread.CurrentThread);
Thread.CurrentThread.WriteLine("Main:lock()前 ", t);
lock (_syncObj1)
{
Thread.CurrentThread.WriteLine("Main:进入Lock1 ", t);
Thread.Sleep(1000);
lock (_syncObj2)
{
Thread.CurrentThread.WriteLine("Main:进入Lock2 ", t);
Thread.Sleep(5000);
Thread.CurrentThread.WriteLine("Main:退出Lock2 ", t);
}
}
Thread.CurrentThread.WriteLine("Main:结束 ", t);
}
}
(二)lock关键词在C#语言中的用法
代码class Program { private static readonly object _syncRoot = new Object(); static Thread t1 = new Thread(new ParameterizedThreadStart(P)); static Thread t2 = new Thread(new ParameterizedThreadStart(P)); static Thread t3 = new Thread(new ParameterizedThreadStart(P)); static void Main(string[] args) { t1.Name = "A"; t2.Name = "B"; t3.Name = "C"; t1.Start(t1); t2.Start(t2); t3.Start(t3); //t1.Join(); //t2.Join(); //t3.Join(); //Console.WriteLine("------------"); //Console.ReadKey(); } static void P(object name) { Thread t = name as Thread; Console.WriteLine("线程名:{0}-1 占用资源\t时间:{5:HH:mm:ss.fff} 当前线程:{1,-18} A:{2,-18} B:{3,-18} C:{4}", t.Name, t.ThreadState.ToString() + " ID:" + t.ManagedThreadId, t1.ThreadState.ToString() + " ID:" + t1.ManagedThreadId, t2.ThreadState.ToString() + " ID:" + t2.ManagedThreadId, t3.ThreadState.ToString() + " ID:" + t3.ManagedThreadId, DateTime.Now); lock (_syncRoot) { Console.WriteLine("线程名:{0}-2 Sleep前\t时间:{5:HH:mm:ss.fff} 当前线程:{1,-18} A:{2,-18} B:{3,-18} C:{4}", t.Name, t.ThreadState.ToString() + " ID:" + t.ManagedThreadId, t1.ThreadState.ToString() + " ID:" + t1.ManagedThreadId, t2.ThreadState.ToString() + " ID:" + t2.ManagedThreadId, t3.ThreadState.ToString() + " ID:" + t3.ManagedThreadId, DateTime.Now); Thread.Sleep(5000); Console.WriteLine("线程名:{0}-3 Sleep后\t时间:{5:HH:mm:ss.fff} 当前线程:{1,-18} A:{2,-18} B:{3,-18} C:{4}", t.Name, t.ThreadState.ToString() + " ID:" + t.ManagedThreadId, t1.ThreadState.ToString() + " ID:" + t1.ManagedThreadId, t2.ThreadState.ToString() + " ID:" + t2.ManagedThreadId, t3.ThreadState.ToString() + " ID:" + t3.ManagedThreadId, DateTime.Now); } Console.WriteLine("线程名:{0}-4 释放资源\t时间:{5:HH:mm:ss.fff} 当前线程:{1,-18} A:{2,-18} B:{3,-18} C:{4}", t.Name, t.ThreadState.ToString() + " ID:" + t.ManagedThreadId, t1.ThreadState.ToString() + " ID:" + t1.ManagedThreadId, t2.ThreadState.ToString() + " ID:" + t2.ManagedThreadId, t3.ThreadState.ToString() + " ID:" + t3.ManagedThreadId, DateTime.Now); } }
执行分析如下:下图列出了代码四次执行输出的结果。