我们用代码来认识一下下面几类的作用
AutoResetEvent / ManualResetEvent Monitor
-----------------------
首先来看看 AutoResetEvent 和 ManualResetEvent
{
static AutoResetEvent are = new AutoResetEvent(false);
static void threadProc()
{
Thread currentThread = Thread.CurrentThread;
for (int i = 0; i < 100; i++)
{
are.WaitOne();
Console.WriteLine("Name:{0} : {1}", currentThread.Name, i);
}
}
static void Main(string[] args)
{
Thread t = new Thread(new ThreadStart(threadProc));
t.Name = "TestThread1";
t.Start();
for (int i = 0; i < 500; i++)
{
if ((i % 5) == 0)
{
are.Set();
Thread.Sleep(10);
}
Console.WriteLine("pulse:{0}", i);
}
while (t.IsAlive)
{
t.Abort();
}
Console.ReadLine();
}
}
正和我们想像的一样,在主线程,每打印5个数,子线程被激活
程序一开始,子线程由于 AutoResetEvent 的 WaitOne方法阻塞 , 这个阻塞只有当收到 AutoResetEvent 的Set方法通知时,才进入运行状态, Set方法发出的通知一方面让处于Wait的子线程进入运行状态,另外一方面,他会阻塞当前线程。
下面我们来看看 Monitor 如何工作
{
static object tLock = new object();
static void threadProc()
{
Thread currentThread = Thread.CurrentThread;
for (int i = 0; i < 100; i++)
{
lock (tLock)
{
Monitor.Pulse(tLock);
Monitor.Wait(tLock);
Console.WriteLine("Name:{0} : {1}", currentThread.Name, i);
}
}
}
static void Main(string[] args)
{
Thread t = new Thread(new ThreadStart(threadProc));
t.Name = "TestThread1";
t.Start();
lock (tLock)
{
for (int i = 0; i < 500; i++)
{
if ((i % 5) == 0)
{
Monitor.Pulse(tLock);
Monitor.Wait(tLock);
}
Console.WriteLine("pulse:{0}", i);
}
}
while (t.IsAlive)
{
t.Abort();
}
Console.ReadLine();
}
}
上面两个程序达到一个目的
在一些时常的线程程序开发中,很多人习惯 Lock(this) ,其实种做法也不是最佳的,在有些情况下会产生的些问题,这里就不讨论了,微软的MSDN建议我们最好Lock一个静态的私有引用类型,建议不用string
希望上面两个小例程能给你解决线程同步问题上带来帮助
上文及例程,代表人个学习的观点,非官方权威解释,不尽之处,请斧正