当前位置: 首页 > news >正文

怎样做约票的网站意思营销融合app

怎样做约票的网站意思,营销融合app,扬州市做网站,微博关键词排名优化三.线程的同步和通讯——生产者和消费者假设这样一种情况#xff0c;两个线程同时维护一个队列#xff0c;如果一个线程对队列中添加元素#xff0c;而另外一个线程从队列中取用元素#xff0c;那么我们称添加元素的线程为生产者#xff0c;称取用元素的线程为消费者。…  三.线程的同步和通讯——生产者和消费者 假设这样一种情况两个线程同时维护一个队列如果一个线程对队列中添加元素而另外一个线程从队列中取用元素那么我们称添加元素的线程为生产者称取用元素的线程为消费者。生产者与消费者问题看起来很简单但是却是多线程应用中一个必须解决的问题它涉及到线程之间的同步和通讯问题。 前面说过每个线程都有自己的资源但是代码区是共享的即每个线程都可以执行相同的函数。但是多线程环境下可能带来的问题就是几个线程同时执行一个函数导致数据的混乱产生不可预料的结果因此我们必须避免这种情况的发生。C#提供了一个关键字lock它可以把一段代码定义为互斥段critical section互斥段在一个时刻内只允许一个线程进入执行而其他线程必须等待。在C#中关键字lock定义如下 lock(expression) statement_block expression代表你希望跟踪的对象通常是对象引用。一般地如果你想保护一个类的实例你可以使用this如果你希望保护一个静态变量如互斥代码段在一个静态方法内部一般使用类名就可以了。而statement_block就是互斥段的代码这段代码在一个时刻内只可能被一个线程执行。   下面是一个使用lock关键字的典型例子我将在注释里向大家说明lock关键字的用法和用途 //lock.csusing System;using System.Threading; internal class Account {  int balance;  Random r new Random();  internal Account(int initial)   {  balance initial;  }   internal int Withdraw(int amount)   {  if (balance 0)   {    file://如果balance小于0则抛出异常    throw new Exception(Negative Balance);  }  //下面的代码保证在当前线程修改balance的值完成之前  //不会有其他线程也执行这段代码来修改balance的值  //因此balance的值是不可能小于0的  lock (this)  {    Console.WriteLine(Current Thread:Thread.CurrentThread.Name);    file://如果没有lock关键字的保护那么可能在执行完if的条件判断之后    file://另外一个线程却执行了balancebalance-amount修改了balance的值    file://而这个修改对这个线程是不可见的所以可能导致这时if的条件已经不成立了    file://但是这个线程却继续执行balancebalance-amount所以导致balance可能小于0    if (balance amount)     {    Thread.Sleep(5);    balance balance - amount;    return amount;    }     else     {    return 0; // transaction rejected    }  }  }  internal void DoTransactions()   {  for (int i 0; i 100; i)     Withdraw(r.Next(-50, 100));  }} internal class Test {  static internal Thread[] threads new Thread[10];  public static void Main()   {  Account acc new Account (0);  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].Namei.ToString();  for (int i 0; i 10; i)     threads[i].Start();  Console.ReadLine();  }} 而多线程公用一个对象时也会出现和公用代码类似的问题这种问题就不应该使用lock关键字了这里需要用到System.Threading中的一个类Monitor我们可以称之为监视器Monitor提供了使线程共享资源的方案。   Monitor类可以锁定一个对象一个线程只有得到这把锁才可以对该对象进行操作。对象锁机制保证了在可能引起混乱的情况下一个时刻只有一个线程可以访问这个对象。Monitor必须和一个具体的对象相关联但是由于它是一个静态的类所以不能使用它来定义对象而且它的所有方法都是静态的不能使用对象来引用。下面代码说明了使用Monitor锁定一个对象的情形 ......Queue oQueuenew Queue();......Monitor.Enter(oQueue);......//现在oQueue对象只能被当前线程操纵了Monitor.Exit(oQueue);//释放锁 如上所示当一个线程调用Monitor.Enter()方法锁定一个对象时这个对象就归它所有了其它线程想要访问这个对象只有等待它使用Monitor.Exit()方法释放锁。为了保证线程最终都能释放锁你可以把Monitor.Exit()方法写在try-catch-finally结构中的finally代码块里。对于任何一个被Monitor锁定的对象内存中都保存着与它相关的一些信息其一是现在持有锁的线程的引用其二是一个预备队列队列中保存了已经准备好获取锁的线程其三是一个等待队列队列中保存着当前正在等待这个对象状态改变的队列的引用。当拥有对象锁的线程准备释放锁时它使用Monitor.Pulse()方法通知等待队列中的第一个线程于是该线程被转移到预备队列中当对象锁被释放时在预备队列中的线程可以立即获得对象锁。 下面是一个展示如何使用lock关键字和Monitor类来实现线程的同步和通讯的例子也是一个典型的生产者与消费者问题。这个例程中生产者线程和消费者线程是交替进行的生产者写入一个数消费者立即读取并且显示我将在注释中介绍该程序的精要所在。用到的系统命名空间如下 using System;using System.Threading; 首先我们定义一个被操作的对象的类Cell在这个类里有两个方法ReadFromCell()和WriteToCell。消费者线程将调用ReadFromCell()读取cellContents的内容并且显示出来生产者进程将调用WriteToCell()方法向cellContents写入数据。 public class Cell{  int cellContents; // Cell对象里边的内容  bool readerFlag false; // 状态标志为true时可以读取为false则正在写入  public int ReadFromCell( )  {  lock(this) // Lock关键字保证了什么请大家看前面对lock的介绍  {    if (!readerFlag)//如果现在不可读取    {     try    {      file://等待WriteToCell方法中调用Monitor.Pulse()方法      Monitor.Wait(this);    }    catch (SynchronizationLockException e)    {      Console.WriteLine(e);    }    catch (ThreadInterruptedException e)    {      Console.WriteLine(e);    }    }    Console.WriteLine(Consume: {0},cellContents);    readerFlag false; file://重置readerFlag标志表示消费行为已经完成    Monitor.Pulse(this); file://通知WriteToCell()方法该方法在另外一个线程中执行等待中  }  return cellContents;  }  public void WriteToCell(int n)  {  lock(this)  {    if (readerFlag)    {    try    {      Monitor.Wait(this);    }    catch (SynchronizationLockException e)    {      file://当同步方法指Monitor类除Enter之外的方法在非同步的代码区被调用      Console.WriteLine(e);    }    catch (ThreadInterruptedException e)    {      file://当线程在等待状态的时候中止       Console.WriteLine(e);    }    }    cellContents n;    Console.WriteLine(Produce: {0},cellContents);    readerFlag true;     Monitor.Pulse(this); file://通知另外一个线程中正在等待的ReadFromCell()方法  }  }}下面定义生产者CellProd和消费者类CellCons它们都只有一个方法ThreadRun()以便在Main()函数中提供给线程的ThreadStart代理对象作为线程的入口。 public class CellProd{  Cell cell; // 被操作的Cell对象  int quantity 1; // 生产者生产次数初始化为1   public CellProd(Cell box, int request)  {  //构造函数  cell box;   quantity request;   }  public void ThreadRun( )  {  for(int looper1; looperquantity; looper)    cell.WriteToCell(looper); file://生产者向操作对象写入信息  }} public class CellCons{  Cell cell;   int quantity 1;   public CellCons(Cell box, int request)  {  cell box;   quantity request;   }  public void ThreadRun( )  {  int valReturned;  for(int looper1; looperquantity; looper)    valReturnedcell.ReadFromCell( );//消费者从操作对象中读取信息  }} 然后在下面这个类MonitorSample的Main()函数中我们要做的就是创建两个线程分别作为生产者和消费者使用CellProd.ThreadRun()方法和CellCons.ThreadRun()方法对同一个Cell对象进行操作。 public class MonitorSample{  public static void Main(String[] args)  {  int result 0; file://一个标志位如果是0表示程序没有出错如果是1表明有错误发生  Cell cell new Cell( );   //下面使用cell初始化CellProd和CellCons两个类生产和消费次数均为20次  CellProd prod new CellProd(cell, 20);   CellCons cons new CellCons(cell, 20);   Thread producer new Thread(new ThreadStart(prod.ThreadRun));  Thread consumer new Thread(new ThreadStart(cons.ThreadRun));  //生产者线程和消费者线程都已经被创建但是没有开始执行   try  {    producer.Start( );    consumer.Start( );     producer.Join( );     consumer.Join( );    Console.ReadLine();  }  catch (ThreadStateException e)  {    file://当线程因为所处状态的原因而不能执行被请求的操作    Console.WriteLine(e);     result 1;   }  catch (ThreadInterruptedException e)  {    file://当线程在等待状态的时候中止    Console.WriteLine(e);     result 1;   }  //尽管Main()函数没有返回值但下面这条语句可以向父进程返回执行结果  Environment.ExitCode result;  }} 大家可以看到在上面的例程中同步是通过等待Monitor.Pulse()来完成的。首先生产者生产了一个值而同一时刻消费者处于等待状态直到收到生产者的“脉冲(Pulse)”通知它生产已经完成此后消费者进入消费状态而生产者开始等待消费者完成操作后将调用Monitor.Pulese()发出的“脉冲”。它的执行结果很简单 Produce: 1Consume: 1Produce: 2Consume: 2Produce: 3Consume: 3......Produce: 20Consume: 20 事实上这个简单的例子已经帮助我们解决了多线程应用程序中可能出现的大问题只要领悟了解决线程间冲突的基本方法很容易把它应用到比较复杂的程序中去。 转载于:https://www.cnblogs.com/supersand/archive/2005/08/27/224185.html
http://wiki.neutronadmin.com/news/447759/

相关文章:

  • 书店网站策划书唐山做网站口碑好的
  • 百度点击软件旺道优化软件
  • 怎么编写一个网站推广是怎么做的
  • 做网站增加流量百度公司是国企还是私企
  • 网站制定兰州网架公司
  • 自己做网站前端开发一个网站域名ip
  • cms建站模板app网站开发公司目前主营业务
  • 有个印度做网站的天天找我科技展厅效果图设计图
  • 超级门户wordpress企业主题杭州网站优化流程
  • 2h1g做视频网站网页网站设计与制作
  • 免费做免费做人爱视频的网站山西省吕梁市天气
  • 可做易企秀的网站网站设计的第一步是
  • 企业网站怎么做省钱兰州网络广告设计方案
  • 买服务器网站wordpress用户如何删除文章
  • 如何做好网站内链新图闻的合作伙伴
  • 用pc机做网站并让外网搜到wordpress4.2.8 留言本
  • 埃及网站后缀wordpress 4.2
  • 做付费网站如何咨询网络服务商
  • 常州h5网站建设网站模板自建站
  • 建设网站五个步骤网站做业务赚钱吗
  • 苏州百度搜索排名优化优化大师是什么软件
  • 个人什么取消网站备案网络游戏服务网
  • 呼和浩特建设工程信息网站html大作业网页代码
  • 手机网站建设服务器郑州大型网站建设价格
  • 网站技术部门架构网络营销工具中最基本最重要的是
  • 阿里云可以做电商网站吗无锡做网站无锡网站设计
  • 直播网站建设需要什么软件黄页应用推广
  • 网站开发需要什么专业的人才河北交通建设投资集团公司网站
  • 常州网站制作费用太原建站
  • 美术馆网站建设要求wordpress4.6 中文