lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。

lock语句根本使用的就是Monitor.Enter和Monitor.Exit,也就是说lock(this)时执行Monitor.Enter(this),大括号结束时执行Monitor.Exit(this).他的意义在于什么呢,对于任何一个对象来说,他在内存中的第一部分放置的是所有方法的地址,第二部分放着一个索引,他指向CLR中的SyncBlock Cache区域中的一个SyncBlock.什么意思呢?就是说,当你执行Monitor.Enter(Object)时,如果object的索引值为负数,就从SyncBlock Cache中选区一个SyncBlock,将其地址放在object的索引中。这样就完成了以object为标志的锁定,其他的线程想再次进行Monitor.Enter(object)操作,将获得object为正数的索引,然后就等待。直到索引变为负数,即线程使用Monitor.Exit(object)将索引变为负数。

使用lock需要注意的地方:

1.lock不能锁定空值某一对象可以指向Null,但Null是不需要被释放的。(请参考:认识全面的null)
2.lock不能锁定string类型,虽然它也是引用类型的。因为字符串类型被CLR“暂留”

这意味着整个程序中任何给定字符串都只有一个实例,就是这同一个对象表示了所有运行的应用程序域的所有线程中的该文本。因此,只要在应用程序进程中的任何位置处具有相同内容的字符串上放置了锁,就将锁定应用程序中该字符串的所有实例。因此,最好锁定不会被暂留的私有或受保护成员。
3.lock锁定的对象是一个程序块的内存边界
4.值类型不能被lock,因为前文标红字的“对象被释放”,值类型不是引用类型的

5.lock就避免锁定public 类型或不受程序控制的对象。
例如,如果该实例可以被公开访问,则 lock(this) 可能会有问题,因为不受控制的代码也可能会锁定该对象。这可能导致死锁,即两个或更多个线程等待释放同一对象。出于同样的原因,锁定公共数据类型(相比于对象)也可能导致问题。
使用lock(this)的时候,类的成员变量的值可能会被不在临界区的方法改值了

应用场景:经常会应用于防止多线程操作导致公用变量值出现不确定的异常,用于确保操作的安全性

// 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 < )
{
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 ; // transaction rejected
}
}
} public void DoTransactions()
{
for (int i = ; i < ; i++)
{
Withdraw(r.Next(, ));
}
}
} class Test
{
static void Main()
{
Thread[] threads = new Thread[];
Account acc = new Account();
for (int i = ; i < ; i++)
{
Thread t = new Thread(new ThreadStart(acc.DoTransactions));
threads[i] = t;
}
for (int i = ; i < ; i++)
{
threads[i].Start();
}
}
}

C# Lock关键字的更多相关文章

  1. lock关键字只不过是C#提供的语法糖

    lock关键字只不过是C#提供的语法糖, 最终使用的还是Monitor类. Monitor类的Enter方法要求传入的参数不为null, 否则会有ArgumentNullException excep ...

  2. C#的lock关键字

    using System; using System.Threading; namespace Test { class Program { //一.Lock定义 //lock 关键字可以用来确保代码 ...

  3. C# 使用lock关键字lock不同的对象

    c# lock关键字的本质 是调用Monitor.Enter(object obj)并且在finally的时候调用Monitor.Exit(obj) 在obj是不同数据类型的时候会出现不同的情况 1. ...

  4. C#中Monitor类、Lock关键字和Mutex类

    线程:线程是进程的独立执行单元,每一个进程都有一个主线程,除了主线程可以包含其他的线程.多线程的意义:多线程有助于改善程序的总体响应性,提高CPU的效率.多线程的应用程序域是相当不稳定的,因为多个线程 ...

  5. C#中的lock关键字有何作用

    作为C#的程序员来说,在遇到线程同步的需求时最常用的就是lock关键字.但如何正确并有效地使用lock,却是能否高效地达到同步要求的关键.正因为如此,程序员需要完全理解lock究竟为程序做了什么. 所 ...

  6. Thread锁 Monitor类、Lock关键字和Mutex类

    Monitor 类锁定一个对象 当多线程公用一个对象时,也会出现和公用代码类似的问题,这种问题就不应该使用lock关键字了,这里需要用到System.Threading中的一个类Monitor,我们可 ...

  7. lock关键字理解

    >可以把lock关键字可以看成 try{ Monitor.Enter(x); //.. } finally{ Monitor.Exit(x); } 这样子的结构,当然使用lock关键字更方便 & ...

  8. C#中的lock关键字;就是lock住一个大家都共同访问的(静态static的)东东就行了

    public class ChatService : IChat //继承IChat接口或者说IChat的实现类 { //定义一个静态对象用于线程部份代码块的锁定,用于lock操作 private s ...

  9. C#中的lock关键字

    前几天与同事激烈讨论了一下,有一点收获,记录起来. 首先给出MSDN的定义: lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断.这是通过在代码块运行期间为给定对象获取互斥锁来实现的. ...

  10. C#中的lock关键字(初识)

    http://kb.cnblogs.com/page/88513/ 首先给出MSDN的定义: lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断.这是通过在代码块运行期间为给定对象获取互 ...

随机推荐

  1. Dubbo学习记录

    参考资料: 官网 Dubbo详细介绍与安装使用过程

  2. Log4j最简入门及实例

    Log4j真的很简单,简单到令人发指的地步.不是要记录日志吗?那就给你一个Log,然后你用Log来写东西就行了,先来一个完整类示例: package test; import org.apache.c ...

  3. a Javascript library for training Deep Learning models

    w强化算法和数学,来迎接机器学习.神经网络. http://cs.stanford.edu/people/karpathy/convnetjs/ ConvNetJS is a Javascript l ...

  4. Python爬虫基础(二)urllib2库的get与post方法

    urllib2默认只支持HTTP/HTTPS的GET和POST方法 一.Get方式 GET请求一般用于我们向服务器获取数据,比如说,我们用百度搜索,在百度搜索框中搜索“秦时明月”,拿到地址栏里有效ur ...

  5. Qt 模拟鼠标点击(QApplication::sendEvent(ui->pushbutton, &event0);)

    QPoint pos(0,0);QMouseEvent event0(QEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton, Qt ...

  6. Xshell连接阿里云Centos6.8

    由于我将xshell更新到了Xshell v5.0 Build 1332,在连接阿里云服务器的时候遇到了一些问题. 以前我登录到服务器的时候直接输入登录密码就行了,但是现在由于openssh服务器类型 ...

  7. 23.如何查看一个keystore的具体签名信息

    keytool -list -v -keystore zhangzu.keystore

  8. 有关ros::spin()和ros::spinonce()若干感受

    ros::spinonce()一般与loop_rate.sleep()同时出现,用来控制处理回调函数的频率,并且没有消息就收来时,就会程序堵塞,不会占用CPU资源. ros::spin(),用于回调函 ...

  9. PAT 1083 List Grades[简单]

    1083 List Grades (25 分) Given a list of N student records with name, ID and grade. You are supposed ...

  10. windows live writer backup

    windows live writer backup备份:http://wlwbackup.codeplex.com/