Monitor的另一种用法

在多线程编程时我们可以使用lock(obj){}代码块来控制关键代码的访问,lock其实是Monitor.Enter(obj)和Monitor.Exit(obj)的一种简单写法(语法糖)。

这个随笔的标题是“Monitor的另一种用法”,所以我们不赘述lock了;我们进入主题,另一种用法可以在一个线程获得对象锁后再释放锁,然后阻塞当前线程执行,直到收到Monitor发出的信号后再继续执行。

这里有两件事一个是获得锁然后释放锁并阻塞当前线程,做这件事儿要用Monitor的Wait()方法

另一件事是线程获得锁,然后执行一段操作并发出信号让第一件事儿中被阻塞的线程继续执行,这需要使用Monitor的Pulse或者PulseAll方法。

请看下面的代码片段:

class BlockingStack<T>
    {
        private readonly Stack<T> stack;
        public BlockingStack(Stack<T> theStack)
        {
            this.stack = theStack;
        }
 
        public void Push(T item)
        {
            lock (stack)
            {
                stack.Push(item);
                if (stack.Count == 1)
                {
                    //这儿发出信号,唤醒在Pop中阻塞的线程
                    Monitor.PulseAll(stack);
                }
            }
        }
 
        public T Pop()
        {
            lock (stack)
            {
                if (stack.Count == 0)
                {
                    //栈是空的,所以等待直到收到信号为止
                    Monitor.Wait(stack);
                }
                T item = stack.Pop();
                return item;
            }
        }
    }

总结: Monitor类还可以锁定对象后释放锁等待另外一个线程发出信号后继续执行。

参考:
http://www.codeproject.com/KB/IP/socketasynceventargssampl.aspx
http://msdn.microsoft.com/en-us/library/system.threading.monitor.wait.aspx
http://msdn.microsoft.com/en-us/library/system.threading.monitor.pulse.aspx

posted @   玉开  阅读(2660)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
历史上的今天:
2008-12-01 C# SQLiteHelper类似SqlHelper类实现存取Sqlite数据库
2008-12-01 使用c#访问microsoft sql server compact (初级)
点击右上角即可分享
微信分享提示