志在指尖
用双手敲打未来

C#多线程的同步与通讯

C#中运用lock和Monitor控制多线程对资源的运用,最常见的消费者和消费者问题就是多线程同步和通讯的经典例子。理解C#多线程的同步与通讯。
一、关于lock和Monitor
lock能够把一段代码定义为互斥段(criticalsection),互斥段在一个时辰内只允许一个线程进入执行,而其它线程必需等候。格式定义如下:
lock(expression)statement_block
expression代表要跟踪的对象,通常是援用。普通地,假如想维护一个类的实例,运用this;假如维护一个静态变量(如互斥代码段在一个静态办法内部),运用类名就能够了。而statement_block就是互斥段的代码。
Monitor用于多线程公用一个对象时使线程共享资源的计划。Monitor必需和一个详细的对象相关联。
二、消费者和消费者问题
假定两个线程同时维护一个队列,假如一个线程对队列中更新元素,而另外一个线程从队列中获取元素,那么我们称更新元素的线程为消费者,称获取元素的线程为消费者。
1、被操作对象
///
;
///被操作对象
///
;
publicclassCounter
{
//更新和读取的数字
privateintnumberOfCounter;
//读操作可执行标志,能够避免死锁的发作
privateboolreadFlag=false;
publicvoidRead()
{
//锁定后,其它读操作等候这一次读操作完成
lock(this)
{
//第一次之行为flase,进入等候
if(!readFlag)
{
try
{
//进入等候读,另一个线程写
Monitor.Wait(this);
}
catch(Exceptionex)
{
Console.WriteLine(ex);
}
}
Console.WriteLine(“消费(获取):{0}”,numberOfCounter);
//重置,消费曾经完成
readFlag=false;
Monitor.Pulse(this);
}
}
publicvoidWrite(intnumber)
{
//锁定后,其它写操作等候这一次写操作完成
lock(this)
{
//第一次readFlag为flase,跳过执行下边的写
//假如当前正在读,等候读操作执行Monitor.Pulse
if(readFlag)
{
try
{
Monitor.Wait(this);
}
catch(Exceptionex)
{
Console.WriteLine(ex);
}
}
numberOfCounter=number;
Console.WriteLine(“消费(更新):{0}”,numberOfCounter);
//重置,消费曾经完成
readFlag=true;
//同步经过等候Pulse来完成
Monitor.Pulse(this);
}
}
}
2、消费者和消费者
///
;
///消费者
///
publicclassCounterWrite
{
Countercounter;
//消费者消费次数
intquantity=1;
publicCounterWrite(Counterbox,intrequest)
{
//结构函数
counter=box;
quantity=request;
}
//消费者向操作对象更新信息
publicvoidWrite()
{
for(inti=1;i<=quantity;i++)
counter.Write(i);
}
}
///
///消费者
///
publicclassCounterRead
{
Countercounter;
//消费者消费次数
intquantity=1;
publicCounterRead(Counterbox,intrequest)
{
//结构函数
counter=box;
quantity=request;
}
//消费者从操作对象中获取信息
publicvoidRead()
{
for(inti=1;i<=quantity;i++)
counter.Read();
}
}
3、线程操作
Countercounter=newCounter();
CounterReadread=newCounterRead(counter,10);
CounterWritewrite=newCounterWrite(counter,10);
Threadth1=newThread(newThreadStart(read.Read));
Threadth2=newThread(newThreadStart(write.Write));
th1.Start();
th2.Start();
th1.Join();
th2.Join();
Console.ReadLine();
经过lock锁定Counter对象的援用,初始readFlag为false控制线程1等候读取:Monitor.Wait(this),
线程2写入,然后更改readFlag,然后执行:Monitor.Pulse(this),通知等候队列中的线程恳求对象状态已发作改动,
线程1锁定this,执行读操作,然后更改readFlag,线程1和线程2交互执行写读的操作。
同时由于readFlag的存在和交替更新,防止了死锁状况的发作。

未经允许不得转载:IT技术网站 » C#多线程的同步与通讯
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

志在指尖 用双手敲打未来

登录/注册IT技术大全

热门IT技术

C#基础入门   SQL server数据库   系统SEO学习教程   WordPress小技巧   WordPress插件   脚本与源码下载