中国著名摄影网站,杭州做网站软件,cms wordpress 区别,建设网站需要展示什么名字介绍介绍对开发人员来说#xff0c;处理关键代码部分的多线程应用程序是非常重要的。Monitor和lock是c#语言中多线程应用程序中提供线程安全的方法(lock关键字的本质就是对Monitor的封装)。两者都提供了一种机制来确保只有一个线程同时执行代码#xff0c;以避免代码功能被其… 介绍介绍对开发人员来说处理关键代码部分的多线程应用程序是非常重要的。Monitor和lock是c#语言中多线程应用程序中提供线程安全的方法(lock关键字的本质就是对Monitor的封装)。两者都提供了一种机制来确保只有一个线程同时执行代码以避免代码功能被其他线程中断锁c#中 Lock关键字确保一个线程同时执行一段代码。lock关键字确保一个线程不进入代码的锁定区而另一个线程在锁定区内。Lock关键字是Monitor的“快捷方式”。namespace Monitor_Lock
{ class Program { static readonly object _object new object(); static void TestLock() { lock (_object) { Thread.Sleep(100); Console.WriteLine(Environment.TickCount); } } static void Main(string[] args) { for (int i 0; i 10; i) { ThreadStart start new ThreadStart(TestLock); new Thread(start).Start(); } Console.ReadLine(); } }
}输出这里我们看到一个静态方法“TestLock”它在对象上使用lock语句。在新线程上多次调用TestLock方法时每次调用该方法都会访问该锁的对象是否释放。Main方法创建十个新线程然后在每个线程上开始调用。方法TestLock被调用十次但是Environment.TickCount计数器显示受保护的方法区域是按顺序执行的大约相隔100毫秒。如果另一个线程试图进入一个锁定的代码它将等待阻塞直到对象被释放。lock关键字通过获取给定对象的互斥锁将语句块标记为一个临界段执行语句然后释放锁MonitorMonitor提供了一种同步对象访问的机制。它可以通过获取一个重要的锁来实现这样一次只有一个线程可以进入给定的代码段。Monitor与lock没有什么不同但是Monitor类对试图访问相同代码锁的各个线程的同步提供了更多的控制。使用Monitor可以确保不允许任何其他线程访问锁所有者正在执行的应用程序代码段除非其他线程使用不同的锁定对象执行代码。Monitor类有以下方法通过获取和释放锁来同步访问代码的某个区域Enter(Object)在指定对象上获取排他锁。Enter(Object, Boolean)获取指定对象上的排他锁并自动设置一个值指示是否获取了该锁。Exit(Object)释放指定对象上的排他锁。IsEntered(Object)确定当前线程是否保留指定对象锁。Pulse(Object)通知等待队列中的线程锁定对象状态的更改。PulseAll(Object)通知所有的等待线程对象状态的更改。TryEnter(Object, TimeSpan, Boolean)在指定的一段时间内尝试获取指定对象上的排他锁并自动设置一个值指示是否获得了该锁。TryEnter(Object, Int32, Boolean)在指定的毫秒数内尝试获取指定对象上的排他锁并自动设置一个值指示是否获取了该锁。TryEnter(Object, TimeSpan)在指定的时间内尝试获取指定对象上的排他锁。TryEnter(Object, Boolean)尝试获取指定对象上的排他锁并自动设置一个值指示是否获取了该锁。TryEnter(Object)尝试获取指定对象的排他锁。TryEnter(Object, Int32)在指定的毫秒数内尝试获取指定对象上的排他锁。Wait(Object, Int32, Boolean)释放对象上的锁并阻止当前线程直到它重新获取该锁。 如果已用指定的超时时间间隔则线程进入就绪队列。 此方法还指定是否在等待之前退出上下文的同步域如果处于同步上下文中的话然后重新获取该同步域。Wait(Object)释放对象上的锁并阻止当前线程直到它重新获取该锁。Wait(Object, Int32)释放对象上的锁并阻止当前线程直到它重新获取该锁。 如果已用指定的超时时间间隔则线程进入就绪队列。Wait(Object, TimeSpan)释放对象上的锁并阻止当前线程直到它重新获取该锁。 如果已用指定的超时时间间隔则线程进入就绪队列。Wait(Object, TimeSpan, Boolean)释放对象上的锁并阻止当前线程直到它重新获取该锁。 如果已用指定的超时时间间隔则线程进入就绪队列。 可以在等待之前退出同步上下文的同步域随后重新获取该域。Monitor锁定对象(即引用类型)而不是值类型。虽然您可以传递一个值类型来进入和退出但是对于每个调用它都是单独装箱的。Wait在锁被持有并等待被通知时释放锁。当Wait被通知时它返回并再次获得锁。Pulse和PulseAll都为等待队列中的下一个线程的开始发出信号。下面是使用Monitor的语法。try
{ int x 1; Monitor.Enter(x); try { // Code that needs to be protected by the monitor. } finally { Monitor.Exit(x); }
}
catch (SynchronizationLockException SyncEx)
{ Console.WriteLine(A SynchronizationLockException occurred. Message:); Console.WriteLine(SyncEx.Message);
}简单例子namespace Monitor_Lock
{ class Program { static readonly object _object new object(); public static void PrintNumbers() { Monitor.Enter(_object); try { for (int i 0; i 5; i) { Thread.Sleep(100); Console.Write(i ,); } Console.WriteLine(); } finally { Monitor.Exit(_object); } } static void TestLock() { lock (_object) { Thread.Sleep(100); Console.WriteLine(Environment.TickCount); } } static void Main(string[] args) { Thread[] Threads new Thread[3]; for (int i 0; i 3; i) { Threads[i] new Thread(new ThreadStart(PrintNumbers)); Threads[i].Name Child i; } foreach (Thread t in Threads) t.Start(); Console.ReadLine(); } }
}输出在c# 4.0中Monitor.Enter(_object,ref _lockTaken)重载函数获取一个独占锁和指定的对象并自动设置一个值该值指示锁是否被获取。class Program
{ static readonly object _object new object(); public static void PrintNumbers() { Boolean _lockTaken false; Monitor.Enter(_object,ref _lockTaken); try { for (int i 0; i 5; i) { Thread.Sleep(100); Console.Write(i ,); } Console.WriteLine(); } finally { if (_lockTaken) { Monitor.Exit(_object); } } }
}与lock等价的Monitor实现Monitor.Enter(object);
try
{ // Your code here...
}
finally
{ Monitor.Exit(object);
}结论Monitor类是一个静态类不能创建它的实例。Monitor类对象使用 Monitor.TryEnter, and Monitor.Exit 方法。一旦锁定了代码区域就可以使用 Monitor.Wait, Monitor.Pulse, and Monitor.PulseAll 等方法。Lock和monitor在多线程中基本上用于相同的目的Monitor的不同之处在于当我们希望对运行特定代码段的多个线程的同步进行更多控制时更有效