• Monitor用法


    Monitor 类通过向单个线程授予对象锁来控制对对象的访问,提供同步对对象的访问的机制

    Monitor 具有以下功能:
    它根据需要与某个对象相关联。
    它是未绑定的,也就是说可以直接从任何上下文调用它。
    不能创建 Monitor 类的实例。

    将为每个同步对象来维护以下信息:
    对当前持有锁的线程的引用。
    对就绪队列的引用,它包含准备获取锁的线程。
    对等待队列的引用,它包含正在等待锁定对象状态变化通知的线程。

    Monitor有几个主要的方法,我们需要了解
    1.Monitor.Enter和Monitor.Exit
    他们两个是一起的,我们在一个方法中,如果调用了Monitor.Enter,那么就必须有相应的Monitory.Exit方法与之对应。这两个方法用于锁定对象和取消锁定对象,在平时的使用中,我们一般用lock取代他们。

    2.Monitor.Wait方法
    当线程调用 Wait 时,它释放对象的锁并进入对象的等待队列,对象的就绪队列中的下一个线程(如果有)获取锁并拥有对对象的独占使用。

    3.Monitor.Pulse方法
    当前线程调用此方法以便向队列中的下一个线程发出锁的信号。接收到脉冲后,等待线程就被移动到就绪队列中。在调用 Pulse 的线程释放锁后,就绪队列中的下一个线程(不一定是接收到脉冲的线程)将获得该锁。

    下面的代码示例说明如何使用以上方法。

    using System;
    using System.Collections.Generic;
    using System.Threading;

    namespace ConsoleApplication6
    {
        
    public class Cell
        
    {
            
    int cellContents; // Cell对象里边的内容
            bool readerFlag = false// 状态标志,为true时可以读取,为false则正在写入
            public int ReadFromCell()
            
    {
                
    lock (this// Lock关键字保证了什么,请大家看前面对lock的介绍
                {
                    
    if (!readerFlag)//如果现在不可读取
                    {
                        
    try
                        
    {
                            
    //等待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//重置readerFlag标志,表示消费行为已经完成
                    Monitor.Pulse(this); //通知WriteToCell()方法(该方法在另外一个线程中执行,等待中)
                }

                
    return cellContents;
            }


            
    public void WriteToCell(int n)
            
    {
                
    lock (this)
                
    {
                    
    if (readerFlag)
                    
    {
                        
    try
                        
    {
                            Monitor.Wait(
    this);
                        }

                        
    catch (SynchronizationLockException e)
                        
    {
                            
    //当同步方法(指Monitor类除Enter之外的方法)在非同步的代码区被调用
                            Console.WriteLine(e);
                        }

                        
    catch (ThreadInterruptedException e)
                        
    {
                            
    //当线程在等待状态的时候中止 
                            Console.WriteLine(e);
                        }

                    }

                    cellContents 
    = n;
                    Console.WriteLine(
    "Produce: {0}", cellContents);
                    readerFlag 
    = true;
                    Monitor.Pulse(
    this); //通知另外一个线程中正在等待的ReadFromCell()方法
                }

            }

        }


        
    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 looper = 1; looper <= quantity; looper++)
                    cell.WriteToCell(looper); 
    //生产者向操作对象写入信息
            }

        }


        
    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 looper = 1; looper <= quantity; looper++)
                    valReturned 
    = cell.ReadFromCell();//消费者从操作对象中读取信息
            }

        }


        
    public class MonitorSample
        
    {
            
    public static void Main(String[] args)
            
    {
                
    int result = 0;
                
    //一个标志位,如果是0表示程序没有出错,如果是1表明有错误发生
                Cell cell = new Cell();

                
    //下面使用cell初始化CellProd和CellCons两个类,生产和消费次数均为20次
                CellProd prod = new CellProd(cell, 5);
                CellCons cons 
    = new CellCons(cell, 5);

                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)
                
    {
                    
    //当线程因为所处状态的原因而不能执行被请求的操作
                    Console.WriteLine(e);
                    result 
    = 1;
                }

                
    catch (ThreadInterruptedException e)
                
    {
                    
    //当线程在等待状态的时候中止
                    Console.WriteLine(e);
                    result 
    = 1;
                }

                
    //尽管Main()函数没有返回值,但下面这条语句可以向父进程返回执行结果
                Environment.ExitCode = result;
            }

        }

    }

      Result:

    Produce: 1
    Consume: 1
    Produce: 2
    Consume: 2
    Produce: 3
    Consume: 3
    Produce: 4
    Consume: 4
    Produce: 5
    Consume: 5

  • 相关阅读:
    移动web开发资源大整合
    移动WEB模拟原声APP滑动删除
    jQuery的live绑定事件在mobile safari(iphone / ipad / ipod)上失效的解决方案
    精仿公众号菜单效果
    javascript markdown 解析器
    第四天
    第三天
    第二天
    第一天
    day5
  • 原文地址:https://www.cnblogs.com/fengfeng/p/1237528.html
Copyright © 2020-2023  润新知