在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
lock关键字
lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。此语句的形式如下: Object thisLock = new Object(); lock (thisLock) { // Critical code section } lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。 lock 调用块开始位置的 Enter 和块结束位置的 Exit。 通常,应避免锁定 public 类型,否则实例将超出代码的控制范围。常见的结构 lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 违反此准则:
最佳做法是定义 private 对象来锁定, 或 private static 对象变量来保护所有实例所共有的数据。 下例使用线程和 lock。只要 lock 语句存在,语句块就是临界区并且 balance 永远不会是负数。 // statements_lock2.cs using System; using System.Threading; class Account { private Object thisLock = new Object(); int balance; Random r = new Random(); public Account(int initial) { balance = initial; } int Withdraw(int amount) { // This condition will never be true unless the lock statement // is commented out: if (balance < 0) { throw new Exception("Negative Balance"); } // Comment out the next line to see the effect of leaving out // the lock keyword: lock(thisLock) { if (balance >= amount) { Console.WriteLine("Balance before Withdrawal : " + balance); Console.WriteLine("Amount to Withdraw : -" + amount); balance = balance - amount; Console.WriteLine("Balance after Withdrawal : " + balance); return amount; } else { return 0; // transaction rejected } } } public void DoTransactions() { for (int i = 0; i < 100; i++) { Withdraw(r.Next(1, 100)); } } } class Test { static void Main() { Thread[] threads = new Thread[10]; Account acc = new Account(1000); for (int i = 0; i < 10; i++) { Thread t = new Thread(new ThreadStart(acc.DoTransactions)); threads[i] = t; } for (int i = 0; i < 10; i++) { threads[i].Start(); } } }
如果一个线程获取了互斥体,则要获取该互斥体的第二个线程将被挂起,直到第一个线程释放该互斥体。 相反,Semaphore 类不强制线程标识。 在 .NET Framework 2.0 版之前,这样不会引发任何异常。 如果出现被放弃的 mutex,通常表明代码中存在严重错误。如果某个线程在未释放互斥体时便退出,受此互斥体保护的数据结构可能处于不一致的状态。如果此数据结构的完整性能得到验证,下一个请求此互斥体所属权的线程就可以处理此异常并继续。因此推荐把Mutex.ReplaceMutex()放在try-catch-finally结构中的finally中。
对于系统范围的 mutex,被放弃的 mutex 可能指示应用程序已突然终止(例如,通过使用 Windows 任务管理器终止)。 Mutex 对象都表示一个单独的局部 mutex。 Mutex 对象来表示同一命名系统 mutex,而且您可以使用 OpenExisting 方法打开现有的命名系统 mutex。 在运行终端服务的服务器上,已命名的系统 mutex 可以具有两级可见性。如果名称以前缀“Global\”开头,则 mutex 在所有终端服务器会话中均为可见。如果名称以前缀“Local\”开头,则 mutex 仅在创建它的终端服务器会话中可见。在这种情况下,服务器上各个其他终端服务器会话中都可以拥有一个名称相同的独立 mutex。如果创建已命名 mutex 时不指定前缀,则它将采用前缀“Local\”。在终端服务器会话中,只是名称前缀不同的两个 mutex 是独立的 mutex,这两个 mutex 对于终端服务器会话中的所有进程均为可见。即:前缀名称“Global\”和“Local\”说明 mutex 名称相对于终端服务器会话(而并非相对于进程)的范围。
Monitor 类Monitor 来确保不会允许其他任何线程访问正在由锁的所有者执行的应用程序代码节,除非另一个线程正在使用其他的锁定对象执行该代码。 Monitor 具有以下功能:
将为每个同步对象来维护以下信息:
|
请发表评论