C#中的lock、Monitor、Mutex学习笔记
来源:互联网 发布:位图软件什么意思 编辑:程序博客网 时间:2024/05/15 09:48
线程:线程是进程的独立执行单元,每一个进程都有一个主线程,除了主线程可以包含其他的线程。
多线程的意义:多线程有助于改善程序的总体响应性,提高CPU的效率。
多线程的应用程序域是相当不稳定的,因为多个线程在同一时间内都能运行共享的功能模块。为了保护应用程序的资源不被破坏,为多线程程序提供了三种加锁的机制,分别是:Monitor类、Lock关键字和Mutex类。
1. lock
lock实现的功能是:使后进入的线程不会中断当前的线程,而是等待当前线程结束后再继续执行。
应用:
private Object thisLock=new object(); lock(thisLock){ //锁定的代码块 }
注意:避免锁定 public 类型,否则实例将超出代码的控制范围。
常见的结构 lock (this)、lock (typeof (MyType)) 和 lock ("myLock")
违反此准则:如果实例可以被公共访问,将出现 lock (this) 问题。
如果 MyType 可以被公共访问,将出现 lock (typeof (MyType)) 问题。
由于进程中使用同一字符串的任何其他代码将共享同一个锁,所以出现 lock(“myLock”) 问题。
最佳做法是定义 private 对象来锁定, 或 private static 对象变量来保护所有实例所共有的数据。
下面举例说明lock的应用:
下面的例子中创建了5个次线程,次线程完成的任务就是:输出线程编码,延迟1秒,然后输出当时的时间
Example:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;namespace ConsoleApplication5 { class Program { static void Main(string[] args) { Console.WriteLine ("程序开始时间:"+DateTime.Now .ToString()); Example ex=new Example (); Thread []threads=new Thread[5]; for (int i=0;i<5;i++) { threads[i]=new Thread (new ThreadStart(ex.OutPut)); threads[i].Name =string.Format ("Worker thread#{0}",i) ; } foreach(Thread t in threads){ t.Start(); } Console.WriteLine("主线程最后一句代码!"+DateTime.Now.ToString()); } } class Example{ private static object thisLock=new object (); public void OutPut() { lock(thisLock){ Console .WriteLine("->{0}",Thread.CurrentThread.Name); Thread.Sleep(1000); Console.WriteLine(DateTime.Now); } } }}
实验结果如下:
图1:加lock
图2:没有lock
从实验结果可以看出,加lock后,程序每次只能执行一个线程,只有当前线程执行完了,才会执行下一个线程未加lock,程序执行混乱,容易阻塞。
2. Monitor
lock是对Monitor的Enter和Exit的一个封装,因此Monitor类的Enter()和Exit()方法的组合使用可以用lock关键字替代。
Monitor类除了具有lock的功能外,还有以下功能:
TryEnter()解决长期死等的问题,如果一个并发经常发生,并且持续时间很长,使用TryEnter,可以有效防止死锁或者长时间 的等待。
Wait()释放对象上的锁,以便允许其他线程锁定和访问该对象。在其他线程访问对象时,调用线程将等待。脉冲信号用于通知等待线程有关对象状态的更改。
Pulse(),PulseAll()向一个或多个等待线程发送信号。该信号通知等待线程锁定对象的状态已更改,并且锁的所有者准备释放该锁。等待线程被放置在对象的就绪队列中以便它可以最后接收对象锁。一旦线程拥有了锁,它就可以检查对象的新状态以查看是否达到所需状态。
注意:Pulse、PulseAll和Wait方法必须从同步的代码块内调用。
3. Mutex(互斥体)
Mutex的突出特点是可以跨应用程序域边界对资源进行独占访问,即可以用于同步不同进程中的线程,这种功能是以牺牲更多的系统资源为代价的。
互斥体Mutex和事件对象EventWaitHandler属于内核对象,利用内核对象进行线程同步,线程必须要在用户模式和内核模式间切换,所以一般效率很低,但利用互斥对象和事件对象这样的内核对象,可以在多个进程中的各个线程间进行同步。
互斥体Mutex类似于一个接力棒,拿到接力棒的线程才可以开始跑,当然接力棒一次只属于一个线程(Thread Affinity),如果这个线程不释放接力棒(Mutex.ReleaseMutex),那么其他所有需要接力棒运行的线程只能等着看热闹。
- C#中的lock、Monitor、Mutex学习笔记
- C#中的lock、Monitor、Mutex
- 再看c#中的lock monitor 和mutex
- C#多线程学习(九)lock,Monitor,Mutex的区别
- [C#学习笔记之多线程2]多线程同步与并发访问共享资源工具—Lock、Monitor、Mutex、Semaphore .
- Ceph Mutex Lock monitor
- c#线程同步中的lock,monitor,同步事件和等待句柄以及mutex的介绍
- C#线程同步——lock,Monitor,Mutex
- C#中lock,Monitor和Mutex的测试代码
- C# 多线程(lock,Monitor,Mutex,同步事件和等待句柄)
- monitor mutex lock in .net
- monitor mutex lock in .net
- lock,Monitor,Mutex的区别
- C#笔记21:多线程之线程同步中的锁定lock、Monitor
- Monitor类、Lock关键字和Mutex类
- C#Monitor类 Lock Mutex类详解
- C#中使用Monitor类、Lock和Mutex类来同步多线程的执行
- C#中使用Monitor类、Lock和Mutex类来同步多线程的执行
- display
- C语言小兵成长记录!
- Chapter 1 认识玩家
- Python——logging模块
- find grep如何避免Is a Directory
- C#中的lock、Monitor、Mutex学习笔记
- 多线程学习笔记4-RunLoop
- 利用pageX、pageY动态的改变div的位置
- Fastlib中rx风格编程
- 修改Team Foundation Server源代码服务器的绑定地址
- 常用快捷键—Webstorm入门指南
- IDEA一键完成格式化、去除无用引用、编译
- golang-Map
- Shell中快速切换多个目录