当两个或更多线程需要同时访问一个共享资源时,系统需要使用同步机制来确保一次只有一个线程使用该资源。Mutex 是同步基元,它只向一个线程授予对共享资源的独占访问权。 如果一个线程获取了互斥体,则要获取该互斥体的第二个线程将被挂起,直到第一个线程释放该互斥体。
可以使用 WaitHandle.WaitOne 方法请求互斥体的所属权。 拥有互斥体的线程可以在对 WaitOne 的重复调用中请求相同的互斥体而不会阻止其执行。 但线程必须调用 ReleaseMutex 方法同样多的次数以释放互斥体的所属权。 Mutex 类强制线程标识,因此互斥体只能由获得它的线程释放。 相反, Semaphore 类不强制线程标识。
如果线程在拥有互斥体时终止,则称此互斥体被放弃。将此 mutex 的状态设置为收到信号,下一个等待线程将获得所有权。从 .NET Framework 2.0 版开始,在获取被放弃 mutex 的下一个线程中将引发 AbandonedMutexException。 在 .NET Framework 2.0 版之前,这样不会引发任何异常。——MSDN
class="csharpcode"> static void Main(string[] args) { for (int i = 0; i < 5; i++) { Thread _currentThead = new Thread(new ParameterizedThreadStart(ProcessWork)); _currentThead.Name = i.ToString(); _currentThead.Start(); } } private static Mutex mutex = new Mutex(); static void ProcessWork(object objNumber) { // mutex.WaitOne(); Thread _currentThread = Thread.CurrentThread; Console.WriteLine(string.Format("【Enter Thread Name:{0}-ManagedThreadId:{1}】-ThreadState:{2}", _currentThread.Name, _currentThread.ManagedThreadId, _currentThread.ThreadState)); Thread.Sleep(500); Console.WriteLine(string.Format("【Leave Thread Name:{0}-ManagedThreadId:{1}】-ThreadState:{2}", _currentThread.Name, _currentThread.ManagedThreadId, _currentThread.ThreadState)); Console.WriteLine("=================================over==============================="); //mutex.ReleaseMutex(); }
当没有Mutex 互斥的效果:
当加上互斥效果:
static void Main(string[] args) { for (int i = 0; i < 5; i++) { Thread _currentThead = new Thread(new ParameterizedThreadStart(ProcessWork)); _currentThead.Name = i.ToString(); _currentThead.Start(); } } private static Mutex mutex = new Mutex(); static void ProcessWork(object objNumber) { mutex.WaitOne(); Thread _currentThread = Thread.CurrentThread; Console.WriteLine(string.Format("【Enter Thread Name:{0}-ManagedThreadId:{1}】-ThreadState:{2}", _currentThread.Name, _currentThread.ManagedThreadId, _currentThread.ThreadState)); Thread.Sleep(500); Console.WriteLine(string.Format("【Leave Thread Name:{0}-ManagedThreadId:{1}】-ThreadState:{2}", _currentThread.Name, _currentThread.ManagedThreadId, _currentThread.ThreadState)); Console.WriteLine("=================================over==============================="); mutex.ReleaseMutex(); }