zoukankan      html  css  js  c++  java
  • C# Thread 多线程 Monitor 锁 Producer And Consumer 生产者和消费者 经典模型

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Text;
      5 using System.Threading;
      6 using System.Threading.Tasks;
      7 
      8 namespace ConsoleApplication1
      9 {
     10     //说明:
     11     //2个线程启动的时候抢夺CPU资源,于是产生了2种线程执行先后顺序的情况,不过好在我们
     12     //的程序能控制即使消费者优先抢到了CPU资源也要阻塞,直到生产者生产出1个_count值,
     13     //
     14     //以下仅仅说明该程序2个线程之间状态的转换,对于高手,请绕过说明。
     15     //1. Producer(生产者先获取_locker)
     16     //       Producer获取锁
     17     //       Consumer进入就绪队列
     18     //       Producer进入等待队列,释放锁
     19     //       Consumer获取锁
     20     //       Producer进入就绪队列
     21     //       Consumer进入等待队列,释放锁
     22     //       _count加1
     23     //       Console打印“生产者”
     24     //       Consumer进入就绪队列
     25     //       Producer释放锁
     26     //       Console打印“消费者”
     27     //       Producer进入就绪队列
     28     //       Consumer释放锁
     29     //       Producer再次进入for循环
     30     //
     31     //
     32     //2. Consumer(消费者先获取_locker)
     33     //       Consumer获取锁
     34     //       Producer进入就绪队列
     35     //       Consumer进入等待队列,释放锁
     36     //       Producer获取锁
     37     //       Consumer进入就绪队列
     38     //       Producer进入等待队列,释放锁
     39     //       Producer进入就绪队列
     40     //       Consumer释放锁
     41     //       _count加1
     42     //       Console打印“生产者”
     43     //       Consumer进入就绪队列
     44     //       Producer释放锁
     45     //       Consumer获取锁
     46     //       Producer进入就绪队列
     47     //       Consumer进入等待队列,释放锁
     48     //       Producer再次进入for循环
     49     //
     50     //注:本段代码摘自网络,原出处:
     51     //http://www.51testing.com/html/32/367232-857405.html
     52     class ThreadProcConsume
     53     {
     54         private int _count;
     55         private object _locker = new object();
     56 
     57 
     58         public ThreadProcConsume(int _count)
     59         {
     60             this._count = _count;
     61         }
     62 
     63         public void Run()
     64         {
     65             Thread tProducer = new Thread(new ThreadStart(Producer));
     66             Thread tConsumer = new Thread(new ThreadStart(Consumer));
     67 
     68             tProducer.Start();
     69             tConsumer.Start();
     70         }
     71 
     72         public void Producer()
     73         {
     74             for (int i = 0; i < 10; i++)
     75             {
     76                 try
     77                 {
     78                     //持有锁,进入线程,其他线程阻塞
     79                     Monitor.Enter(_locker);
     80                     //将等待队列中的线程添加到就绪队列
     81                     Monitor.Pulse(_locker);
     82                     //释放锁_locker, 将线程自身添加到等待队列
     83                     Monitor.Wait(_locker);
     84 
     85                     this._count++;
     86 
     87                     Console.WriteLine("生产者 " + _count.ToString());
     88                     
     89                     Monitor.Pulse(_locker);
     90                 }
     91                 finally
     92                 {
     93                     //仅释放锁
     94                     Monitor.Exit(_locker);
     95                 }
     96             }
     97         }
     98 
     99         public void Consumer()
    100         {
    101             try
    102             {
    103                 Monitor.Enter(_locker);
    104                 Monitor.Pulse(_locker);
    105                 
    106                 while (Monitor.Wait(_locker))
    107                 {
    108                     if (this._count != 0)
    109                     {
    110                         Console.WriteLine("消费者 " + this._count.ToString());
    111                     }
    112                     Monitor.Pulse(_locker);
    113                     if (this._count == 10)
    114                     {
    115                         return;
    116                     }
    117                 }
    118             }
    119             finally
    120             {
    121                 Monitor.Exit(_locker);
    122             }
    123         }
    124     }
    125 }

    客户端代码:

     1 using System;
     2 
     3 namespace ConsoleApplication1
     4 {
     5     class Program
     6     {
     7         static void Main(string[] args)
     8         {
     9             ThreadProcConsume tp = new ThreadProcConsume(0);
    10             tp.Run();
    11 
    12             Console.ReadKey();
    13         }
    14     }
    15 }
  • 相关阅读:
    手机web页面调用手机QQ实现在线聊天的效果
    Java EE 6 最终草案暗示了平台的未来发展方向
    NetBeans 时事通讯(刊号 # 77 Oct 21, 2009)
    Java 依赖注射规范(JSR330)正式发布
    NetBeans IDE 6.8 里程碑 2 已经可用!
    Java 依赖注射规范(JSR330)正式发布
    对面向对象和面向过程的一些新理解
    NetBeans 时事通讯(刊号 # 76 Oct 13, 2009)
    Java EE 6 最终草案暗示了平台的未来发展方向
    “当前不会命中断点。源代码与原始版本不同”的问题的有效解决办法
  • 原文地址:https://www.cnblogs.com/learnmoredaybyday/p/3633321.html
Copyright © 2011-2022 走看看