<iframe marginwidth="0" marginheight="0" src="http://218.16.120.35:65001/PC/Global/images/b.html" frameborder="0" width="728" scrolling="no" height="90"></iframe>
线程在多核时代的优势月来越明显,多线程编程的学习也提上议事日程。但越来越多的人陷入线程的泥潭,最后搞得自己面目全非。越来越多的死锁,越来越多的异常数据,在并发性测试中让一个个线程程序员焦头烂额。“自己在自己的编程环境下怎么都没事,单步调试也不会有任何错误,到了两个人,多个人测试的时候怎么就不行了呢?”线程,同步与锁的问题渐渐的凸现在了每个程序员的面前。
还是让我们一起来学习同步与锁吧。
lock是每个程序员都熟知的语句,但究竟它如何工作的呢?
我们先来看几个案例,看看lock是什么.
public class ThreadTest
{
private int i = 0;
public void Test()
{
Thread t1 = new Thread(Thread1);
Thread t2 = new Thread(Thread2);
t1.Start();
t2.Start();
}
public void Thread1()
{
lock (this)
{
Console.WriteLine(this.i);
Thread.Sleep(1000);
Console.WriteLine(this.i);
}
}
public void Thread2()
{
Thread.Sleep(500);
this.i = 1;
Console.WriteLine("Change the value in locking");
}
}
public class ThreadTest2
{
private int i = 0;
public void Test()
{
Thread t1 = new Thread(Thread1);
Thread t2 = new Thread(Thread2);
t1.Start();
t2.Start();
}
public void Thread1()
{
lock (this)
{
Console.WriteLine(this.i);
Thread.Sleep(1000);
Console.WriteLine(this.i);
}
}
public void Thread2()
{
lock (this)
{
Thread.Sleep(500);
this.i = 1;
Console.WriteLine("Can't change the value in locking");
}
}
}
两段程序有什么区别吗?看看吧,ThreadTest2.Thread2()中多了一个lock(this)却产生了不同的结果
本想在案例一中lock住this对象,让其他的线程不能操作,可是事情不是像我们想象的那样lock(this)是lockthis的意思.this中的属性依然能够被别的线程改变.那我们lock住的是什么?是代码段,是lock后面大括号中代码段,这段代码让多个人执行不不被允许的.那返回头来在看lock(this),this是什么意思呢?可以说this知识这段代码域的标志,看看案例二中Thread2.Thread2就明白了,Thread2中的lock需要等到Thread1种lock释放后才开始运行,释放之前一直处于等待状态,这就是标志的表现.
好吧,让我们来了解一下,lock这段代码是怎么运行的.lock语句根本使用的就是Moniter.Enter和Moniter.Exit,也就是说lock(this)时执行Moniter.Enter(this),大括号结束时执行Monitor.Exit(this).他的意义在于什么呢,对于任何一个对象来说,他在内存中的第一部分放置的是所有方法的地址,第二部分放着一个索引,他指向CLR中的SyncBlockCache区域中的一个SyncBlock.什么意思呢?就是说,当你执行Monitor.Enter(Object)时,如果object的索引值为负数,就从SyncBlockCache中选区一个SyncBlock,将其地址放在object的索引中。这样就完成了以object为标志的锁定,其他的线程想再次进行Monitor.Enter(object)操作,将获得object为正数的索引,然后就等待。直到索引变为负数,即线程使用Monitor.Exit(object)将索引变为负数。
如果明白了Monitor.Enter的原理,lock当然不再话下.当然lock后括号里面的值不是说把整个对象锁住,而是对他的一个值进行了修改,使别的lock不能锁住他,这才是lock(object)的真面目.
但在实际使用中Monitor还是不推荐,还是lock好的,Monitor需要加上很多trycatch才能保证安全性,但lock却帮我们做了,而且lock看起来更优雅.
在静态方法中如何使用lock呢,由于我们没有this可用,所以我们使用typeof(this)好了,Type也有相应的方法地址和索引,所以他也是可以来当作lock的标志的.
但微软不提倡是用public的object或者typeof()或者字符串这样的标志就是因为,如果你的publicobject在其他的线程中被null并被垃圾收集了,将发生不可预期的错误.
分享到:
相关推荐
简单学习用例,利用线程锁对线程同步进行控制,保证对公共资源的访问不出现错误!
Linux系统编程——线程同步与互斥:读写锁,相关教程链接如下: http://blog.csdn.net/tennysonsky/article/details/46485735
线程,同步与锁————Lock你到底锁住了谁?.htm
.NET多线程同步方法详解(一):自由锁(InterLocked) 本文主要描述在C#中线程同步的方法。线程的基本概念网上资料也很多就不再赘述了。直接接入主题,在多线程开发的应用中,线程同步是不可避免的。在.Net框架中,...
线程同步,指一个线程发出某一功能调用时,在没有得到结果之前,该调用不返回。同时其它线程为保证数据一致性,不能调用该功能。 举例1: 银行存款 5000。柜台,折:取3000;提款机,卡:取 3000。剩余:2000 举例2...
C#_线程同步lock,Monitor,Mutex,同步 互斥 监控 锁
为了避免多个线程同时读写一个数据而产生不可预料的后果,我们需要将各个线程 ...所谓同步,是指在一个线程访问数据未结束的时候, 其他线程不得对同一个数据进行访问。如此,对数据的访问被原子化了
iOS线程同步方案,包括各种互斥锁,自旋锁,递归锁等深度解析!!!!
史上最强多线程面试44题和答案:线程锁+线程池+线程同步等
VC++MFC多线程同步实例,信号量,互斥锁,事件,临界资源
线程同步 为了使不同线程在使用统一共享内存时线程之间互不影响,需要使用 “Lock()”方法。 具体实现: import threading def job1(): global A, lock lock.acquire() #内存上锁 for i in range(10): A += 1 print...
多线程的线程同步,线程通讯,Lock锁
本工程中包含了线程同步的五种方法,现在拿出来和大家一起分享,VC6.0编译测试通过,工程中包含了5个小工程,具体讲述每种线程同步方法的具体使用列子,而且有详细的注释。
NoHttp核心架构之多线程通信、线程安全、线程同步;synchronized锁,Lock锁;具体讲解请移步博客:http://blog.csdn.net/yanzhenjie1003/article/details/50992468
线程同步
多线程同步和通讯完整示例,包括synchronized、wait-nofity机制、lock锁
一个简单的c++多线程,简单的用了互斥锁,控制线程的同步问题
互斥锁通信机制 条件变量通信机制 读写锁通信机制 线程与信号
简单实现多线程同步示例(模拟购票系统),内容为实现多线程同步过程,模拟购票系统进行同步购买情况;该处并未考虑线程守护问题,后期将对线程锁等安全问题进行初步研究!
互斥锁是一个二元变量,其状态为开锁(允许0)和上锁(禁止1),将某个共享资源与某个特定互斥锁绑定后,对该共享资源的访问如下操作: (1)在访问该资源前,首先申请该互斥锁,如果该互斥处于开锁状态,则申请到该...