• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C#教程 > 深入多线程之:用Wait与Pulse模拟一些同步构造的应用详解

深入多线程之:用Wait与Pulse模拟一些同步构造的应用详解

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了线程wait,java线程wait,多线程wait,线程中wait,java多线程wait等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

你可能在上篇文章中《深入多线程之:双向信号与竞赛的用法分析》注意到了这个模式:两个Waiting 循环都要下面的构造:

lock(_locker)
{
        while(!_flag) Monitor.Wait(_locker);
        _flag = false;
}
</div>
在这里_flag被另一线程设置为true。这是,从作用上讲,这里在模仿AutoResetEvent。如果我们将 _flag = false;去掉,那么我们就得到了一个基本的ManualResetEvent.

让我们使用Wait和Pulse来为ManualResetEvent完成剩余的代码吧。

        void WaitOne()
        {
            lock (_locker)
            {
                while (!_signal) Monitor.Wait(_locker);
            }
        }

        void Set()
        {
            lock (_locker) { _signal = true; Monitor.PulseAll(_locker); }
        }

        void Reset() { lock (_locker) _signal = false; }
</div>
在这里使用PulseAll,是因为可能有很多阻塞的线程。

如果在WaitOne方法中增加_signal=false就可以简单的模拟AutoResetEvent.例如:

Lock(_locker) {_signal = true; Monitor.Pulse(_locker);}

如果使用的是int类型的_signal 标志,那么我们可以得到一个最基本的Semaphore.

Waiting Queues and PulseAll

当多余一个线程在同一个对象上面等待的时候,一个 “等待队列(waiting queue)” 就形成了。

每一次调用Pulse都会释放在”等待队列”头部的一个线程。下面的图形象的展示了这一点:

 

线程调用Monitor.Enter 进入ReadyQueue. 等待获取锁,成功获取锁后,如果正常的执行,那么之后会调用Monitor.Exit退出,

否则如果获取了锁之后发现需要等待其他的线程或者是其他阻塞条件,那么调用Wait方法,就进入了等待队列,

当等待的线程完成并调用Pulse后,处在WaitingQueue头部的线程就被 Pulse了,等待CPU调度 。之后再次进入Ready Queue,重新获取锁。


Countdown

借助Wait和Pulse,我们可以实现CountdownEvent的主要功能。例如:

        public void Singnal() { AddCount(-1); } //将计数减一

        public void AddCount(int amount)
        {
            lock (_locker)
            {
                _value += amount; //将计数增加或减少
                if (_value <= 0) Monitor.PulseAll(_locker);//如果value<=0,说明所有等待的任务都完成了。
            }
        }

        public void Wait()
        {
            lock (_locker)
            {
                //只要计数 > 0 就等待。
                while (_value > 0)
                {
                    Monitor.Wait(_locker);
                }
            }
        }
}
</div>
这和我们上次的代码几乎一致,只是这次我们的阻塞条件基于一个整型_value标志。

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 深入多线程之:Wait与Pulse的使用详解
  • 深入多线程之:用Wait与Pulse模拟一些同步构造的应用详解

相关文章

  • 2017-05-28C#制作简单的多人在线即时交流聊天室
  • 2017-05-28C#使用回溯法解决背包问题实例分析
  • 2017-05-28测试stringbuilder运行效率示例
  • 2017-05-28C# 获取属性名的方法
  • 2017-05-28C#求数组中元素全排列的方法
  • 2017-05-28C# 骑士飞行棋的源码(分享)
  • 2017-05-28WPF中不规则窗体与WindowsFormsHost控件兼容问题的解决方法
  • 2017-05-28C#接口归纳总结实例详解
  • 2017-05-28用C#的params关键字实现方法形参个数可变示例
  • 2017-05-28Repeater中添加按钮实现点击按钮获取某一行数据的方法

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C#读取中文文件出现乱码的解决方法
    • 用C#把文件转换为XML的代码
    • C# 设计模式之单例模式归纳总结
    • C#下载网页并在控制台输出的方法
    • C#图像处理之浮雕效果实现方法
    • C#图像边缘检测(Roberts)的方法
    • DevExpress之ChartControl用法实例总结
    • C#集合遍历时删除和增加元素的方法
    • 怎么利用c#修改services的Startup type
    • C# WinForm窗体编程中处理数字的正确操作方法

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有